source: trunk/packages/xen-3.1/xen-3.1/tools/ioemu/gdbstub.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 23.4 KB
Line 
1/*
2 * gdb server stub
3 *
4 * Copyright (c) 2003-2005 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 "config.h"
21#ifdef CONFIG_USER_ONLY
22#include <stdlib.h>
23#include <stdio.h>
24#include <stdarg.h>
25#include <string.h>
26#include <errno.h>
27#include <unistd.h>
28#include <fcntl.h>
29
30#include "qemu.h"
31#else
32#include "vl.h"
33#endif
34
35#include "qemu_socket.h"
36#ifdef _WIN32
37/* XXX: these constants may be independent of the host ones even for Unix */
38#ifndef SIGTRAP
39#define SIGTRAP 5
40#endif
41#ifndef SIGINT
42#define SIGINT 2
43#endif
44#else
45#include <signal.h>
46#endif
47
48//#define DEBUG_GDB
49
50enum RSState {
51    RS_IDLE,
52    RS_GETLINE,
53    RS_CHKSUM1,
54    RS_CHKSUM2,
55};
56/* XXX: This is not thread safe.  Do we care?  */
57static int gdbserver_fd = -1;
58
59typedef struct GDBState {
60    CPUState *env; /* current CPU */
61    enum RSState state; /* parsing state */
62    int fd;
63    char line_buf[4096];
64    int line_buf_index;
65    int line_csum;
66#ifdef CONFIG_USER_ONLY
67    int running_state;
68#endif
69} GDBState;
70
71#ifdef CONFIG_USER_ONLY
72/* XXX: remove this hack.  */
73static GDBState gdbserver_state;
74#endif
75
76static int get_char(GDBState *s)
77{
78    uint8_t ch;
79    int ret;
80
81    for(;;) {
82        ret = recv(s->fd, &ch, 1, 0);
83        if (ret < 0) {
84            if (errno != EINTR && errno != EAGAIN)
85                return -1;
86        } else if (ret == 0) {
87            return -1;
88        } else {
89            break;
90        }
91    }
92    return ch;
93}
94
95static void put_buffer(GDBState *s, const uint8_t *buf, int len)
96{
97    int ret;
98
99    while (len > 0) {
100        ret = send(s->fd, buf, len, 0);
101        if (ret < 0) {
102            if (errno != EINTR && errno != EAGAIN)
103                return;
104        } else {
105            buf += ret;
106            len -= ret;
107        }
108    }
109}
110
111static inline int fromhex(int v)
112{
113    if (v >= '0' && v <= '9')
114        return v - '0';
115    else if (v >= 'A' && v <= 'F')
116        return v - 'A' + 10;
117    else if (v >= 'a' && v <= 'f')
118        return v - 'a' + 10;
119    else
120        return 0;
121}
122
123static inline int tohex(int v)
124{
125    if (v < 10)
126        return v + '0';
127    else
128        return v - 10 + 'a';
129}
130
131static void memtohex(char *buf, const uint8_t *mem, int len)
132{
133    int i, c;
134    char *q;
135    q = buf;
136    for(i = 0; i < len; i++) {
137        c = mem[i];
138        *q++ = tohex(c >> 4);
139        *q++ = tohex(c & 0xf);
140    }
141    *q = '\0';
142}
143
144static void hextomem(uint8_t *mem, const char *buf, int len)
145{
146    int i;
147
148    for(i = 0; i < len; i++) {
149        mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
150        buf += 2;
151    }
152}
153
154/* return -1 if error, 0 if OK */
155static int put_packet(GDBState *s, char *buf)
156{
157    char buf1[3];
158    int len, csum, ch, i;
159
160#ifdef DEBUG_GDB
161    printf("reply='%s'\n", buf);
162#endif
163
164    for(;;) {
165        buf1[0] = '$';
166        put_buffer(s, buf1, 1);
167        len = strlen(buf);
168        put_buffer(s, buf, len);
169        csum = 0;
170        for(i = 0; i < len; i++) {
171            csum += buf[i];
172        }
173        buf1[0] = '#';
174        buf1[1] = tohex((csum >> 4) & 0xf);
175        buf1[2] = tohex((csum) & 0xf);
176
177        put_buffer(s, buf1, 3);
178
179        ch = get_char(s);
180        if (ch < 0)
181            return -1;
182        if (ch == '+')
183            break;
184    }
185    return 0;
186}
187
188#if defined(TARGET_I386)
189
190static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
191{
192    uint32_t *registers = (uint32_t *)mem_buf;
193    int i, fpus;
194
195    for(i = 0; i < 8; i++) {
196        registers[i] = env->regs[i];
197    }
198    registers[8] = env->eip;
199    registers[9] = env->eflags;
200    registers[10] = env->segs[R_CS].selector;
201    registers[11] = env->segs[R_SS].selector;
202    registers[12] = env->segs[R_DS].selector;
203    registers[13] = env->segs[R_ES].selector;
204    registers[14] = env->segs[R_FS].selector;
205    registers[15] = env->segs[R_GS].selector;
206    /* XXX: convert floats */
207    for(i = 0; i < 8; i++) {
208        memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);
209    }
210    registers[36] = env->fpuc;
211    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
212    registers[37] = fpus;
213    registers[38] = 0; /* XXX: convert tags */
214    registers[39] = 0; /* fiseg */
215    registers[40] = 0; /* fioff */
216    registers[41] = 0; /* foseg */
217    registers[42] = 0; /* fooff */
218    registers[43] = 0; /* fop */
219   
220    for(i = 0; i < 16; i++)
221        tswapls(&registers[i]);
222    for(i = 36; i < 44; i++)
223        tswapls(&registers[i]);
224    return 44 * 4;
225}
226
227static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
228{
229    uint32_t *registers = (uint32_t *)mem_buf;
230    int i;
231
232    for(i = 0; i < 8; i++) {
233        env->regs[i] = tswapl(registers[i]);
234    }
235    env->eip = tswapl(registers[8]);
236    env->eflags = tswapl(registers[9]);
237#if defined(CONFIG_USER_ONLY)
238#define LOAD_SEG(index, sreg)\
239            if (tswapl(registers[index]) != env->segs[sreg].selector)\
240                cpu_x86_load_seg(env, sreg, tswapl(registers[index]));
241            LOAD_SEG(10, R_CS);
242            LOAD_SEG(11, R_SS);
243            LOAD_SEG(12, R_DS);
244            LOAD_SEG(13, R_ES);
245            LOAD_SEG(14, R_FS);
246            LOAD_SEG(15, R_GS);
247#endif
248}
249
250#elif defined (TARGET_PPC)
251static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
252{
253    uint32_t *registers = (uint32_t *)mem_buf, tmp;
254    int i;
255
256    /* fill in gprs */
257    for(i = 0; i < 32; i++) {
258        registers[i] = tswapl(env->gpr[i]);
259    }
260    /* fill in fprs */
261    for (i = 0; i < 32; i++) {
262        registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
263        registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1));
264    }
265    /* nip, msr, ccr, lnk, ctr, xer, mq */
266    registers[96] = tswapl(env->nip);
267    registers[97] = tswapl(do_load_msr(env));
268    tmp = 0;
269    for (i = 0; i < 8; i++)
270        tmp |= env->crf[i] << (32 - ((i + 1) * 4));
271    registers[98] = tswapl(tmp);
272    registers[99] = tswapl(env->lr);
273    registers[100] = tswapl(env->ctr);
274    registers[101] = tswapl(do_load_xer(env));
275    registers[102] = 0;
276
277    return 103 * 4;
278}
279
280static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
281{
282    uint32_t *registers = (uint32_t *)mem_buf;
283    int i;
284
285    /* fill in gprs */
286    for (i = 0; i < 32; i++) {
287        env->gpr[i] = tswapl(registers[i]);
288    }
289    /* fill in fprs */
290    for (i = 0; i < 32; i++) {
291        *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
292        *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
293    }
294    /* nip, msr, ccr, lnk, ctr, xer, mq */
295    env->nip = tswapl(registers[96]);
296    do_store_msr(env, tswapl(registers[97]));
297    registers[98] = tswapl(registers[98]);
298    for (i = 0; i < 8; i++)
299        env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
300    env->lr = tswapl(registers[99]);
301    env->ctr = tswapl(registers[100]);
302    do_store_xer(env, tswapl(registers[101]));
303}
304#elif defined (TARGET_SPARC)
305static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
306{
307    target_ulong *registers = (target_ulong *)mem_buf;
308    int i;
309
310    /* fill in g0..g7 */
311    for(i = 0; i < 8; i++) {
312        registers[i] = tswapl(env->gregs[i]);
313    }
314    /* fill in register window */
315    for(i = 0; i < 24; i++) {
316        registers[i + 8] = tswapl(env->regwptr[i]);
317    }
318#ifndef TARGET_SPARC64
319    /* fill in fprs */
320    for (i = 0; i < 32; i++) {
321        registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
322    }
323    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
324    registers[64] = tswapl(env->y);
325    {
326        target_ulong tmp;
327
328        tmp = GET_PSR(env);
329        registers[65] = tswapl(tmp);
330    }
331    registers[66] = tswapl(env->wim);
332    registers[67] = tswapl(env->tbr);
333    registers[68] = tswapl(env->pc);
334    registers[69] = tswapl(env->npc);
335    registers[70] = tswapl(env->fsr);
336    registers[71] = 0; /* csr */
337    registers[72] = 0;
338    return 73 * sizeof(target_ulong);
339#else
340    /* fill in fprs */
341    for (i = 0; i < 64; i += 2) {
342        uint64_t tmp;
343
344        tmp = (uint64_t)tswap32(*((uint32_t *)&env->fpr[i])) << 32;
345        tmp |= tswap32(*((uint32_t *)&env->fpr[i + 1]));
346        registers[i/2 + 32] = tmp;
347    }
348    registers[64] = tswapl(env->pc);
349    registers[65] = tswapl(env->npc);
350    registers[66] = tswapl(env->tstate[env->tl]);
351    registers[67] = tswapl(env->fsr);
352    registers[68] = tswapl(env->fprs);
353    registers[69] = tswapl(env->y);
354    return 70 * sizeof(target_ulong);
355#endif
356}
357
358static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
359{
360    target_ulong *registers = (target_ulong *)mem_buf;
361    int i;
362
363    /* fill in g0..g7 */
364    for(i = 0; i < 7; i++) {
365        env->gregs[i] = tswapl(registers[i]);
366    }
367    /* fill in register window */
368    for(i = 0; i < 24; i++) {
369        env->regwptr[i] = tswapl(registers[i + 8]);
370    }
371#ifndef TARGET_SPARC64
372    /* fill in fprs */
373    for (i = 0; i < 32; i++) {
374        *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
375    }
376    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
377    env->y = tswapl(registers[64]);
378    PUT_PSR(env, tswapl(registers[65]));
379    env->wim = tswapl(registers[66]);
380    env->tbr = tswapl(registers[67]);
381    env->pc = tswapl(registers[68]);
382    env->npc = tswapl(registers[69]);
383    env->fsr = tswapl(registers[70]);
384#else
385    for (i = 0; i < 64; i += 2) {
386        *((uint32_t *)&env->fpr[i]) = tswap32(registers[i/2 + 32] >> 32);
387        *((uint32_t *)&env->fpr[i + 1]) = tswap32(registers[i/2 + 32] & 0xffffffff);
388    }
389    env->pc = tswapl(registers[64]);
390    env->npc = tswapl(registers[65]);
391    env->tstate[env->tl] = tswapl(registers[66]);
392    env->fsr = tswapl(registers[67]);
393    env->fprs = tswapl(registers[68]);
394    env->y = tswapl(registers[69]);
395#endif
396}
397#elif defined (TARGET_ARM)
398static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
399{
400    int i;
401    uint8_t *ptr;
402
403    ptr = mem_buf;
404    /* 16 core integer registers (4 bytes each).  */
405    for (i = 0; i < 16; i++)
406      {
407        *(uint32_t *)ptr = tswapl(env->regs[i]);
408        ptr += 4;
409      }
410    /* 8 FPA registers (12 bytes each), FPS (4 bytes).
411       Not yet implemented.  */
412    memset (ptr, 0, 8 * 12 + 4);
413    ptr += 8 * 12 + 4;
414    /* CPSR (4 bytes).  */
415    *(uint32_t *)ptr = tswapl (cpsr_read(env));
416    ptr += 4;
417
418    return ptr - mem_buf;
419}
420
421static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
422{
423    int i;
424    uint8_t *ptr;
425
426    ptr = mem_buf;
427    /* Core integer registers.  */
428    for (i = 0; i < 16; i++)
429      {
430        env->regs[i] = tswapl(*(uint32_t *)ptr);
431        ptr += 4;
432      }
433    /* Ignore FPA regs and scr.  */
434    ptr += 8 * 12 + 4;
435    cpsr_write (env, tswapl(*(uint32_t *)ptr), 0xffffffff);
436}
437#elif defined (TARGET_MIPS)
438static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
439{
440    int i;
441    uint8_t *ptr;
442
443    ptr = mem_buf;
444    for (i = 0; i < 32; i++)
445      {
446        *(uint32_t *)ptr = tswapl(env->gpr[i]);
447        ptr += 4;
448      }
449
450    *(uint32_t *)ptr = tswapl(env->CP0_Status);
451    ptr += 4;
452
453    *(uint32_t *)ptr = tswapl(env->LO);
454    ptr += 4;
455
456    *(uint32_t *)ptr = tswapl(env->HI);
457    ptr += 4;
458
459    *(uint32_t *)ptr = tswapl(env->CP0_BadVAddr);
460    ptr += 4;
461
462    *(uint32_t *)ptr = tswapl(env->CP0_Cause);
463    ptr += 4;
464
465    *(uint32_t *)ptr = tswapl(env->PC);
466    ptr += 4;
467
468    /* 32 FP registers, fsr, fir, fp.  Not yet implemented.  */
469
470    return ptr - mem_buf;
471}
472
473static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
474{
475    int i;
476    uint8_t *ptr;
477
478    ptr = mem_buf;
479    for (i = 0; i < 32; i++)
480      {
481        env->gpr[i] = tswapl(*(uint32_t *)ptr);
482        ptr += 4;
483      }
484
485    env->CP0_Status = tswapl(*(uint32_t *)ptr);
486    ptr += 4;
487
488    env->LO = tswapl(*(uint32_t *)ptr);
489    ptr += 4;
490
491    env->HI = tswapl(*(uint32_t *)ptr);
492    ptr += 4;
493
494    env->CP0_BadVAddr = tswapl(*(uint32_t *)ptr);
495    ptr += 4;
496
497    env->CP0_Cause = tswapl(*(uint32_t *)ptr);
498    ptr += 4;
499
500    env->PC = tswapl(*(uint32_t *)ptr);
501    ptr += 4;
502}
503#elif defined (TARGET_SH4)
504static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
505{
506  uint32_t *ptr = (uint32_t *)mem_buf;
507  int i;
508
509#define SAVE(x) *ptr++=tswapl(x)
510  if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
511      for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]);
512  } else {
513      for (i = 0; i < 8; i++) SAVE(env->gregs[i]);
514  }
515  for (i = 8; i < 16; i++) SAVE(env->gregs[i]);
516  SAVE (env->pc);
517  SAVE (env->pr);
518  SAVE (env->gbr);
519  SAVE (env->vbr);
520  SAVE (env->mach);
521  SAVE (env->macl);
522  SAVE (env->sr);
523  SAVE (0); /* TICKS */
524  SAVE (0); /* STALLS */
525  SAVE (0); /* CYCLES */
526  SAVE (0); /* INSTS */
527  SAVE (0); /* PLR */
528
529  return ((uint8_t *)ptr - mem_buf);
530}
531
532static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
533{
534  uint32_t *ptr = (uint32_t *)mem_buf;
535  int i;
536
537#define LOAD(x) (x)=*ptr++;
538  if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
539      for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
540  } else {
541      for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
542  }
543  for (i = 8; i < 16; i++) LOAD(env->gregs[i]);
544  LOAD (env->pc);
545  LOAD (env->pr);
546  LOAD (env->gbr);
547  LOAD (env->vbr);
548  LOAD (env->mach);
549  LOAD (env->macl);
550  LOAD (env->sr);
551}
552#else
553static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
554{
555    return 0;
556}
557
558static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
559{
560}
561
562#endif
563
564static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
565{
566    const char *p;
567    int ch, reg_size, type;
568    char buf[4096];
569    uint8_t mem_buf[2000];
570    uint32_t *registers;
571    target_ulong addr, len;
572   
573#ifdef DEBUG_GDB
574    printf("command='%s'\n", line_buf);
575#endif
576    p = line_buf;
577    ch = *p++;
578    switch(ch) {
579    case '?':
580        /* TODO: Make this return the correct value for user-mode.  */
581        snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
582        put_packet(s, buf);
583        break;
584    case 'c':
585        if (*p != '\0') {
586            addr = strtoull(p, (char **)&p, 16);
587#if defined(TARGET_I386)
588            env->eip = addr;
589#elif defined (TARGET_PPC)
590            env->nip = addr;
591#elif defined (TARGET_SPARC)
592            env->pc = addr;
593            env->npc = addr + 4;
594#elif defined (TARGET_ARM)
595            env->regs[15] = addr;
596#elif defined (TARGET_SH4)
597            env->pc = addr;
598#endif
599        }
600#ifdef CONFIG_USER_ONLY
601        s->running_state = 1;
602#else
603        vm_start();
604#endif
605        return RS_IDLE;
606    case 's':
607        if (*p != '\0') {
608            addr = strtoul(p, (char **)&p, 16);
609#if defined(TARGET_I386)
610            env->eip = addr;
611#elif defined (TARGET_PPC)
612            env->nip = addr;
613#elif defined (TARGET_SPARC)
614            env->pc = addr;
615            env->npc = addr + 4;
616#elif defined (TARGET_ARM)
617            env->regs[15] = addr;
618#elif defined (TARGET_SH4)
619            env->pc = addr;
620#endif
621        }
622        cpu_single_step(env, 1);
623#ifdef CONFIG_USER_ONLY
624        s->running_state = 1;
625#else
626        vm_start();
627#endif
628        return RS_IDLE;
629    case 'g':
630        reg_size = cpu_gdb_read_registers(env, mem_buf);
631        memtohex(buf, mem_buf, reg_size);
632        put_packet(s, buf);
633        break;
634    case 'G':
635        registers = (void *)mem_buf;
636        len = strlen(p) / 2;
637        hextomem((uint8_t *)registers, p, len);
638        cpu_gdb_write_registers(env, mem_buf, len);
639        put_packet(s, "OK");
640        break;
641    case 'm':
642        addr = strtoull(p, (char **)&p, 16);
643        if (*p == ',')
644            p++;
645        len = strtoull(p, NULL, 16);
646        if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0) {
647            put_packet (s, "E14");
648        } else {
649            memtohex(buf, mem_buf, len);
650            put_packet(s, buf);
651        }
652        break;
653    case 'M':
654        addr = strtoull(p, (char **)&p, 16);
655        if (*p == ',')
656            p++;
657        len = strtoull(p, (char **)&p, 16);
658        if (*p == ':')
659            p++;
660        hextomem(mem_buf, p, len);
661        if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)
662            put_packet(s, "E14");
663        else
664            put_packet(s, "OK");
665        break;
666    case 'Z':
667        type = strtoul(p, (char **)&p, 16);
668        if (*p == ',')
669            p++;
670        addr = strtoull(p, (char **)&p, 16);
671        if (*p == ',')
672            p++;
673        len = strtoull(p, (char **)&p, 16);
674        if (type == 0 || type == 1) {
675            if (cpu_breakpoint_insert(env, addr) < 0)
676                goto breakpoint_error;
677            put_packet(s, "OK");
678        } else {
679        breakpoint_error:
680            put_packet(s, "E22");
681        }
682        break;
683    case 'z':
684        type = strtoul(p, (char **)&p, 16);
685        if (*p == ',')
686            p++;
687        addr = strtoull(p, (char **)&p, 16);
688        if (*p == ',')
689            p++;
690        len = strtoull(p, (char **)&p, 16);
691        if (type == 0 || type == 1) {
692            cpu_breakpoint_remove(env, addr);
693            put_packet(s, "OK");
694        } else {
695            goto breakpoint_error;
696        }
697        break;
698#ifdef CONFIG_USER_ONLY
699    case 'q':
700        if (strncmp(p, "Offsets", 7) == 0) {
701            TaskState *ts = env->opaque;
702
703            sprintf(buf, "Text=%x;Data=%x;Bss=%x", ts->info->code_offset,
704                ts->info->data_offset, ts->info->data_offset);
705            put_packet(s, buf);
706            break;
707        }
708        /* Fall through.  */
709#endif
710    default:
711        //        unknown_command:
712        /* put empty packet */
713        buf[0] = '\0';
714        put_packet(s, buf);
715        break;
716    }
717    return RS_IDLE;
718}
719
720extern void tb_flush(CPUState *env);
721
722#ifndef CONFIG_USER_ONLY
723static void gdb_vm_stopped(void *opaque, int reason)
724{
725    GDBState *s = opaque;
726    char buf[256];
727    int ret;
728
729    /* disable single step if it was enable */
730    cpu_single_step(s->env, 0);
731
732    if (reason == EXCP_DEBUG) {
733        tb_flush(s->env);
734        ret = SIGTRAP;
735    } else if (reason == EXCP_INTERRUPT) {
736        ret = SIGINT;
737    } else {
738        ret = 0;
739    }
740    snprintf(buf, sizeof(buf), "S%02x", ret);
741    put_packet(s, buf);
742}
743#endif
744
745static void gdb_read_byte(GDBState *s, int ch)
746{
747    CPUState *env = s->env;
748    int i, csum;
749    char reply[1];
750
751#ifndef CONFIG_USER_ONLY
752    if (vm_running) {
753        /* when the CPU is running, we cannot do anything except stop
754           it when receiving a char */
755        vm_stop(EXCP_INTERRUPT);
756    } else 
757#endif
758    {
759        switch(s->state) {
760        case RS_IDLE:
761            if (ch == '$') {
762                s->line_buf_index = 0;
763                s->state = RS_GETLINE;
764            }
765            break;
766        case RS_GETLINE:
767            if (ch == '#') {
768            s->state = RS_CHKSUM1;
769            } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
770                s->state = RS_IDLE;
771            } else {
772            s->line_buf[s->line_buf_index++] = ch;
773            }
774            break;
775        case RS_CHKSUM1:
776            s->line_buf[s->line_buf_index] = '\0';
777            s->line_csum = fromhex(ch) << 4;
778            s->state = RS_CHKSUM2;
779            break;
780        case RS_CHKSUM2:
781            s->line_csum |= fromhex(ch);
782            csum = 0;
783            for(i = 0; i < s->line_buf_index; i++) {
784                csum += s->line_buf[i];
785            }
786            if (s->line_csum != (csum & 0xff)) {
787                reply[0] = '-';
788                put_buffer(s, reply, 1);
789                s->state = RS_IDLE;
790            } else {
791                reply[0] = '+';
792                put_buffer(s, reply, 1);
793                s->state = gdb_handle_packet(s, env, s->line_buf);
794            }
795            break;
796        }
797    }
798}
799
800#ifdef CONFIG_USER_ONLY
801int
802gdb_handlesig (CPUState *env, int sig)
803{
804  GDBState *s;
805  char buf[256];
806  int n;
807
808  if (gdbserver_fd < 0)
809    return sig;
810
811  s = &gdbserver_state;
812
813  /* disable single step if it was enabled */
814  cpu_single_step(env, 0);
815  tb_flush(env);
816
817  if (sig != 0)
818    {
819      snprintf(buf, sizeof(buf), "S%02x", sig);
820      put_packet(s, buf);
821    }
822
823  sig = 0;
824  s->state = RS_IDLE;
825  s->running_state = 0;
826  while (s->running_state == 0) {
827      n = read (s->fd, buf, 256);
828      if (n > 0)
829        {
830          int i;
831
832          for (i = 0; i < n; i++)
833            gdb_read_byte (s, buf[i]);
834        }
835      else if (n == 0 || errno != EAGAIN)
836        {
837          /* XXX: Connection closed.  Should probably wait for annother
838             connection before continuing.  */
839          return sig;
840        }
841  }
842  return sig;
843}
844
845/* Tell the remote gdb that the process has exited.  */
846void gdb_exit(CPUState *env, int code)
847{
848  GDBState *s;
849  char buf[4];
850
851  if (gdbserver_fd < 0)
852    return;
853
854  s = &gdbserver_state;
855
856  snprintf(buf, sizeof(buf), "W%02x", code);
857  put_packet(s, buf);
858}
859
860#else
861static void gdb_read(void *opaque)
862{
863    GDBState *s = opaque;
864    int i, size;
865    uint8_t buf[4096];
866
867    size = recv(s->fd, buf, sizeof(buf), 0);
868    if (size < 0)
869        return;
870    if (size == 0) {
871        /* end of connection */
872        qemu_del_vm_stop_handler(gdb_vm_stopped, s);
873        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
874        qemu_free(s);
875        vm_start();
876    } else {
877        for(i = 0; i < size; i++)
878            gdb_read_byte(s, buf[i]);
879    }
880}
881
882#endif
883
884static void gdb_accept(void *opaque)
885{
886    GDBState *s;
887    struct sockaddr_in sockaddr;
888    socklen_t len;
889    int val, fd;
890
891    for(;;) {
892        len = sizeof(sockaddr);
893        fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
894        if (fd < 0 && errno != EINTR) {
895            perror("accept");
896            return;
897        } else if (fd >= 0) {
898            break;
899        }
900    }
901
902    /* set short latency */
903    val = 1;
904    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
905   
906#ifdef CONFIG_USER_ONLY
907    s = &gdbserver_state;
908    memset (s, 0, sizeof (GDBState));
909#else
910    s = qemu_mallocz(sizeof(GDBState));
911    if (!s) {
912        close(fd);
913        return;
914    }
915#endif
916    s->env = first_cpu; /* XXX: allow to change CPU */
917    s->fd = fd;
918
919#ifdef CONFIG_USER_ONLY
920    fcntl(fd, F_SETFL, O_NONBLOCK);
921#else
922    socket_set_nonblock(fd);
923
924    /* stop the VM */
925    vm_stop(EXCP_INTERRUPT);
926
927    /* start handling I/O */
928    qemu_set_fd_handler(s->fd, gdb_read, NULL, s);
929    /* when the VM is stopped, the following callback is called */
930    qemu_add_vm_stop_handler(gdb_vm_stopped, s);
931#endif
932}
933
934static int gdbserver_open(int port)
935{
936    struct sockaddr_in sockaddr;
937    int fd, val, ret;
938
939    fd = socket(PF_INET, SOCK_STREAM, 0);
940    if (fd < 0) {
941        perror("socket");
942        return -1;
943    }
944
945    /* allow fast reuse */
946    val = 1;
947    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
948
949    sockaddr.sin_family = AF_INET;
950    sockaddr.sin_port = htons(port);
951    sockaddr.sin_addr.s_addr = 0;
952    ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
953    if (ret < 0) {
954        perror("bind");
955        return -1;
956    }
957    ret = listen(fd, 0);
958    if (ret < 0) {
959        perror("listen");
960        return -1;
961    }
962#ifndef CONFIG_USER_ONLY
963    socket_set_nonblock(fd);
964#endif
965    return fd;
966}
967
968int gdbserver_start(int port)
969{
970    gdbserver_fd = gdbserver_open(port);
971    if (gdbserver_fd < 0)
972        return -1;
973    /* accept connections */
974#ifdef CONFIG_USER_ONLY
975    gdb_accept (NULL);
976#else
977    qemu_set_fd_handler(gdbserver_fd, gdb_accept, NULL, NULL);
978#endif
979    return 0;
980}
Note: See TracBrowser for help on using the repository browser.