Mercurial > repos > blastem
comparison gdb_remote.c @ 456:249d24973682
Initial work on GDB remote debugging support
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 04 Sep 2013 19:34:19 -0700 |
parents | |
children | 140af5509ce7 |
comparison
equal
deleted
inserted
replaced
455:be9c7b3e25ee | 456:249d24973682 |
---|---|
1 #include "blastem.h" | |
2 #include <unistd.h> | |
3 #include <fcntl.h> | |
4 #include <stddef.h> | |
5 #include <stdlib.h> | |
6 #include <stdio.h> | |
7 | |
8 #define INITIAL_BUFFER_SIZE 4096 | |
9 | |
10 char * buf = NULL; | |
11 char * curbuf = NULL; | |
12 size_t bufsize; | |
13 int cont = 0; | |
14 int expect_break_response=0; | |
15 uint32_t resume_pc; | |
16 | |
17 void gdb_debug_enter(genesis_context * gen, uint32_t pc) | |
18 { | |
19 resume_pc = pc; | |
20 while(!cont) | |
21 { | |
22 } | |
23 cont = 0; | |
24 } | |
25 | |
26 void gdb_run_command(genesis_context * gen, char * command) | |
27 { | |
28 switch(*command) | |
29 { | |
30 case 'c': | |
31 if (*(command+1) != 0) { | |
32 resume_pc = | |
33 } | |
34 cont = 1; | |
35 expect_break_response = 1; | |
36 break; | |
37 case 's': | |
38 | |
39 } | |
40 } | |
41 | |
42 void gdb_run_commands(genesis_context * gen) | |
43 { | |
44 int enter_debugger = 0; | |
45 char * cur = buf; | |
46 while(cur < curbuf); | |
47 { | |
48 if(*cur == '$') { | |
49 cur++ | |
50 char * start = cur; | |
51 while (cur < curbuf && *cur != '#') { | |
52 cur++; | |
53 } | |
54 if (*cur == '#') { | |
55 //check to make sure we've received the checksum bytes | |
56 if (curbuf-cur >= 2) { | |
57 //TODO: verify checksum | |
58 //Null terminate payload | |
59 //send acknowledgement | |
60 write(FILENO_STDOUT, "+", 1); | |
61 gdb_run_command(genesis_context * gen, start); | |
62 cur += 2; | |
63 } else { | |
64 cur = start - 1; | |
65 break; | |
66 } | |
67 } else { | |
68 cur = start - 1; | |
69 break; | |
70 } | |
71 } else { | |
72 if (*cur == 0x03) { | |
73 enter_debugger = 1; | |
74 } | |
75 cur++; | |
76 } | |
77 } | |
78 | |
79 //FIXME | |
80 if (consumed == curbuf-buf) { | |
81 curbuf = buf; | |
82 } else if (consumed > 0) { | |
83 memmove(buf, buf + consumed, curbuf - buf - consumed); | |
84 curbuf -= consumed; | |
85 } | |
86 } | |
87 | |
88 void gdb_command_poll(genesis_context * gen) | |
89 { | |
90 for(;;) | |
91 { | |
92 if (curbuf == buf + bufsize) { | |
93 //buffer is full, expand it | |
94 bufsize *= 2; | |
95 buf = realloc(buf, bufsize); | |
96 if (!buf) { | |
97 fprintf(stderr, "Failed to grow GDB command buffer to %d bytes\n", (int)bufsize); | |
98 exit(1); | |
99 } | |
100 curbuf = buf + bufsize/2; | |
101 } | |
102 int numread = read(STDIN_FILENO, buf, bufsize - (curbuf-buf)); | |
103 if (numread < 0) { | |
104 if (errno == EAGAIN || errno == EWOULDBLOCK) { | |
105 return; | |
106 } else { | |
107 fprintf(stderr, "Error %d while reading GDB commands from stdin", errno); | |
108 exit(1); | |
109 } | |
110 } else if (numread == 0) { | |
111 exit(0); | |
112 } | |
113 gdb_run_commands(genesis_context * gen); | |
114 } | |
115 } | |
116 | |
117 void gdb_remote_init() | |
118 { | |
119 fcntl(STDIN_FILENO, FD_SETFL, O_NONBLOCK); | |
120 buf = malloc(INITIAL_BUFFER_SIZE); | |
121 curbuf = buf; | |
122 bufzie = INITIAL_BUFFER_SIZE; | |
123 } |