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