rlm@1
|
1 #include <cstdlib>
|
rlm@1
|
2 #include <cstdio>
|
rlm@1
|
3 #include <cstring>
|
rlm@1
|
4
|
rlm@1
|
5 #ifndef WIN32
|
rlm@1
|
6 # include <unistd.h>
|
rlm@1
|
7 # include <sys/socket.h>
|
rlm@1
|
8 # include <netdb.h>
|
rlm@1
|
9 # ifdef HAVE_NETINET_IN_H
|
rlm@1
|
10 # include <netinet/in.h>
|
rlm@1
|
11 # endif // HAVE_NETINET_IN_H
|
rlm@1
|
12 # ifdef HAVE_ARPA_INET_H
|
rlm@1
|
13 # include <arpa/inet.h>
|
rlm@1
|
14 # else // ! HAVE_ARPA_INET_H
|
rlm@1
|
15 # define socklen_t int
|
rlm@1
|
16 # endif // ! HAVE_ARPA_INET_H
|
rlm@1
|
17 #else // WIN32
|
rlm@1
|
18 # include "../win32/stdafx.h"
|
rlm@1
|
19 # include <winsock.h>
|
rlm@1
|
20 # include <io.h>
|
rlm@1
|
21 # define socklen_t int
|
rlm@1
|
22 # define close closesocket
|
rlm@1
|
23 # define read _read
|
rlm@1
|
24 # define write _write
|
rlm@1
|
25 #endif // WIN32
|
rlm@1
|
26
|
rlm@1
|
27 #include "GBA.h"
|
rlm@1
|
28 #include "GBAGlobals.h"
|
rlm@1
|
29
|
rlm@1
|
30 extern bool debugger;
|
rlm@1
|
31 extern void CPUUpdateCPSR();
|
rlm@1
|
32 #ifdef SDL
|
rlm@1
|
33 extern void (*dbgMain)();
|
rlm@1
|
34 extern void (*dbgSignal)(int, int);
|
rlm@1
|
35 extern void debuggerMain();
|
rlm@1
|
36 extern void debuggerSignal(int, int);
|
rlm@1
|
37 #endif
|
rlm@1
|
38
|
rlm@1
|
39 int remotePort = 55555;
|
rlm@1
|
40 int remoteSignal = 5;
|
rlm@1
|
41 int remoteSocket = -1;
|
rlm@1
|
42 int remoteListenSocket = -1;
|
rlm@1
|
43 bool remoteConnected = false;
|
rlm@1
|
44 bool remoteResumed = false;
|
rlm@1
|
45
|
rlm@1
|
46 int (*remoteSendFnc)(char *, int) = NULL;
|
rlm@1
|
47 int (*remoteRecvFnc)(char *, int) = NULL;
|
rlm@1
|
48 bool (*remoteInitFnc)() = NULL;
|
rlm@1
|
49 void (*remoteCleanUpFnc)() = NULL;
|
rlm@1
|
50
|
rlm@1
|
51 #if (defined WIN32 && !defined SDL)
|
rlm@1
|
52 void remoteSetSockets(SOCKET l, SOCKET r)
|
rlm@1
|
53 {
|
rlm@20
|
54 remoteSocket = r;
|
rlm@20
|
55 remoteListenSocket = l;
|
rlm@1
|
56 }
|
rlm@1
|
57
|
rlm@1
|
58 #endif
|
rlm@1
|
59
|
rlm@1
|
60 int remoteTcpSend(char *data, int len)
|
rlm@1
|
61 {
|
rlm@20
|
62 return send(remoteSocket, data, len, 0);
|
rlm@1
|
63 }
|
rlm@1
|
64
|
rlm@1
|
65 int remoteTcpRecv(char *data, int len)
|
rlm@1
|
66 {
|
rlm@20
|
67 return recv(remoteSocket, data, len, 0);
|
rlm@1
|
68 }
|
rlm@1
|
69
|
rlm@1
|
70 bool remoteTcpInit()
|
rlm@1
|
71 {
|
rlm@20
|
72 if (remoteSocket == -1)
|
rlm@20
|
73 {
|
rlm@20
|
74 #ifdef WIN32
|
rlm@20
|
75 WSADATA wsaData;
|
rlm@20
|
76 int error = WSAStartup(MAKEWORD(1, 1), &wsaData);
|
rlm@20
|
77 #endif // WIN32
|
rlm@20
|
78 int s = socket(PF_INET, SOCK_STREAM, 0);
|
rlm@20
|
79
|
rlm@20
|
80 remoteListenSocket = s;
|
rlm@20
|
81
|
rlm@20
|
82 if (s < 0)
|
rlm@20
|
83 {
|
rlm@20
|
84 fprintf(stderr, "Error opening socket\n");
|
rlm@20
|
85 exit(-1);
|
rlm@20
|
86 }
|
rlm@20
|
87 int tmp = 1;
|
rlm@20
|
88 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof(tmp));
|
rlm@20
|
89
|
rlm@20
|
90 // char hostname[256];
|
rlm@20
|
91 // gethostname(hostname, 256);
|
rlm@20
|
92
|
rlm@20
|
93 // hostent *ent = gethostbyname(hostname);
|
rlm@20
|
94 // unsigned long a = *((unsigned long *)ent->h_addr);
|
rlm@20
|
95
|
rlm@20
|
96 sockaddr_in addr;
|
rlm@20
|
97 addr.sin_family = AF_INET;
|
rlm@20
|
98 addr.sin_port = htons(remotePort);
|
rlm@20
|
99 addr.sin_addr.s_addr = htonl(0);
|
rlm@20
|
100 int count = 0;
|
rlm@20
|
101 while (count < 3)
|
rlm@20
|
102 {
|
rlm@20
|
103 if (bind(s, (sockaddr *)&addr, sizeof(addr)))
|
rlm@20
|
104 {
|
rlm@20
|
105 addr.sin_port = htons(ntohs(addr.sin_port)+1);
|
rlm@20
|
106 }
|
rlm@20
|
107 else
|
rlm@20
|
108 break;
|
rlm@20
|
109 }
|
rlm@20
|
110 if (count == 3)
|
rlm@20
|
111 {
|
rlm@20
|
112 fprintf(stderr, "Error binding \n");
|
rlm@20
|
113 exit(-1);
|
rlm@20
|
114 }
|
rlm@20
|
115
|
rlm@20
|
116 fprintf(stderr, "Listening for a connection at port %d\n",
|
rlm@20
|
117 ntohs(addr.sin_port));
|
rlm@20
|
118
|
rlm@20
|
119 if (listen(s, 1))
|
rlm@20
|
120 {
|
rlm@20
|
121 fprintf(stderr, "Error listening\n");
|
rlm@20
|
122 exit(-1);
|
rlm@20
|
123 }
|
rlm@20
|
124 socklen_t len = sizeof(addr);
|
rlm@20
|
125
|
rlm@20
|
126 #ifdef WIN32
|
rlm@20
|
127 int flag = 0;
|
rlm@20
|
128 ioctlsocket(s, FIONBIO, (unsigned long *)&flag);
|
rlm@20
|
129 #endif // WIN32
|
rlm@20
|
130 int s2 = accept(s, (sockaddr *)&addr, &len);
|
rlm@20
|
131 if (s2 > 0)
|
rlm@20
|
132 {
|
rlm@20
|
133 fprintf(stderr, "Got a connection from %s %d\n",
|
rlm@20
|
134 inet_ntoa((in_addr)addr.sin_addr),
|
rlm@20
|
135 ntohs(addr.sin_port));
|
rlm@20
|
136 }
|
rlm@20
|
137 else
|
rlm@1
|
138 {
|
rlm@1
|
139 #ifdef WIN32
|
rlm@20
|
140 int error = WSAGetLastError();
|
rlm@1
|
141 #endif // WIN32
|
rlm@1
|
142 }
|
rlm@20
|
143 char dummy;
|
rlm@20
|
144 recv(s2, &dummy, 1, 0);
|
rlm@20
|
145 if (dummy != '+')
|
rlm@20
|
146 {
|
rlm@20
|
147 fprintf(stderr, "ACK not received\n");
|
rlm@20
|
148 exit(-1);
|
rlm@20
|
149 }
|
rlm@20
|
150 remoteSocket = s2;
|
rlm@20
|
151 // close(s);
|
rlm@20
|
152 }
|
rlm@20
|
153 return true;
|
rlm@1
|
154 }
|
rlm@1
|
155
|
rlm@1
|
156 void remoteTcpCleanUp()
|
rlm@1
|
157 {
|
rlm@20
|
158 if (remoteSocket > 0)
|
rlm@20
|
159 {
|
rlm@20
|
160 fprintf(stderr, "Closing remote socket\n");
|
rlm@20
|
161 close(remoteSocket);
|
rlm@20
|
162 remoteSocket = -1;
|
rlm@20
|
163 }
|
rlm@20
|
164 if (remoteListenSocket > 0)
|
rlm@20
|
165 {
|
rlm@20
|
166 fprintf(stderr, "Closing listen socket\n");
|
rlm@20
|
167 close(remoteListenSocket);
|
rlm@20
|
168 remoteListenSocket = -1;
|
rlm@20
|
169 }
|
rlm@1
|
170 }
|
rlm@1
|
171
|
rlm@1
|
172 int remotePipeSend(char *data, int len)
|
rlm@1
|
173 {
|
rlm@20
|
174 int res = write(1, data, len);
|
rlm@20
|
175 return res;
|
rlm@1
|
176 }
|
rlm@1
|
177
|
rlm@1
|
178 int remotePipeRecv(char *data, int len)
|
rlm@1
|
179 {
|
rlm@20
|
180 int res = read(0, data, len);
|
rlm@20
|
181 return res;
|
rlm@1
|
182 }
|
rlm@1
|
183
|
rlm@1
|
184 bool remotePipeInit()
|
rlm@1
|
185 {
|
rlm@20
|
186 char dummy;
|
rlm@20
|
187 read(0, &dummy, 1);
|
rlm@20
|
188 if (dummy != '+')
|
rlm@20
|
189 {
|
rlm@20
|
190 fprintf(stderr, "ACK not received\n");
|
rlm@20
|
191 exit(-1);
|
rlm@20
|
192 }
|
rlm@1
|
193
|
rlm@20
|
194 return true;
|
rlm@1
|
195 }
|
rlm@1
|
196
|
rlm@1
|
197 void remotePipeCleanUp()
|
rlm@1
|
198 {}
|
rlm@1
|
199
|
rlm@1
|
200 void remoteSetPort(int port)
|
rlm@1
|
201 {
|
rlm@20
|
202 remotePort = port;
|
rlm@1
|
203 }
|
rlm@1
|
204
|
rlm@1
|
205 void remoteSetProtocol(int p)
|
rlm@1
|
206 {
|
rlm@20
|
207 if (p == 0)
|
rlm@20
|
208 {
|
rlm@20
|
209 remoteSendFnc = remoteTcpSend;
|
rlm@20
|
210 remoteRecvFnc = remoteTcpRecv;
|
rlm@20
|
211 remoteInitFnc = remoteTcpInit;
|
rlm@20
|
212 remoteCleanUpFnc = remoteTcpCleanUp;
|
rlm@20
|
213 }
|
rlm@20
|
214 else
|
rlm@20
|
215 {
|
rlm@20
|
216 remoteSendFnc = remotePipeSend;
|
rlm@20
|
217 remoteRecvFnc = remotePipeRecv;
|
rlm@20
|
218 remoteInitFnc = remotePipeInit;
|
rlm@20
|
219 remoteCleanUpFnc = remotePipeCleanUp;
|
rlm@20
|
220 }
|
rlm@1
|
221 }
|
rlm@1
|
222
|
rlm@1
|
223 void remoteInit()
|
rlm@1
|
224 {
|
rlm@20
|
225 if (remoteInitFnc)
|
rlm@20
|
226 remoteInitFnc();
|
rlm@1
|
227 }
|
rlm@1
|
228
|
rlm@1
|
229 void remotePutPacket(char *packet)
|
rlm@1
|
230 {
|
rlm@20
|
231 char *hex = "0123456789abcdef";
|
rlm@20
|
232 char buffer[1024];
|
rlm@1
|
233
|
rlm@20
|
234 int count = strlen(packet);
|
rlm@1
|
235
|
rlm@20
|
236 unsigned char csum = 0;
|
rlm@1
|
237
|
rlm@20
|
238 char *p = buffer;
|
rlm@20
|
239 *p++ = '$';
|
rlm@1
|
240
|
rlm@20
|
241 for (int i = 0; i < count; i++)
|
rlm@20
|
242 {
|
rlm@20
|
243 csum += packet[i];
|
rlm@20
|
244 *p++ = packet[i];
|
rlm@20
|
245 }
|
rlm@20
|
246 *p++ = '#';
|
rlm@20
|
247 *p++ = hex[csum>>4];
|
rlm@20
|
248 *p++ = hex[csum & 15];
|
rlm@20
|
249 *p++ = 0;
|
rlm@20
|
250 // printf("Sending %s\n", buffer);
|
rlm@20
|
251 remoteSendFnc(buffer, count + 4);
|
rlm@1
|
252
|
rlm@20
|
253 char c = 0;
|
rlm@20
|
254 remoteRecvFnc(&c, 1);
|
rlm@20
|
255 /*
|
rlm@20
|
256 if(c == '+')
|
rlm@20
|
257 printf("ACK\n");
|
rlm@20
|
258 else if(c=='-')
|
rlm@20
|
259 printf("NACK\n");
|
rlm@20
|
260 */
|
rlm@1
|
261 }
|
rlm@1
|
262
|
rlm@1
|
263 void remoteOutput(char *s, u32 addr)
|
rlm@1
|
264 {
|
rlm@20
|
265 char buffer[16384];
|
rlm@1
|
266
|
rlm@20
|
267 char *d = buffer;
|
rlm@20
|
268 *d++ = 'O';
|
rlm@1
|
269
|
rlm@20
|
270 if (s)
|
rlm@20
|
271 {
|
rlm@20
|
272 char c = *s++;
|
rlm@20
|
273 while (c)
|
rlm@1
|
274 {
|
rlm@20
|
275 sprintf(d, "%02x", c);
|
rlm@20
|
276 d += 2;
|
rlm@20
|
277 c = *s++;
|
rlm@1
|
278 }
|
rlm@20
|
279 }
|
rlm@20
|
280 else
|
rlm@20
|
281 {
|
rlm@20
|
282 char c = debuggerReadByte(addr);
|
rlm@20
|
283 addr++;
|
rlm@20
|
284 while (c)
|
rlm@1
|
285 {
|
rlm@20
|
286 sprintf(d, "%02x", c);
|
rlm@20
|
287 d += 2;
|
rlm@20
|
288 c = debuggerReadByte(addr);
|
rlm@20
|
289 addr++;
|
rlm@1
|
290 }
|
rlm@20
|
291 }
|
rlm@20
|
292 remotePutPacket(buffer);
|
rlm@20
|
293 // fprintf(stderr, "Output sent %s\n", buffer);
|
rlm@1
|
294 }
|
rlm@1
|
295
|
rlm@1
|
296 void remoteSendSignal()
|
rlm@1
|
297 {
|
rlm@20
|
298 char buffer[1024];
|
rlm@20
|
299 sprintf(buffer, "S%02x", remoteSignal);
|
rlm@20
|
300 remotePutPacket(buffer);
|
rlm@1
|
301 }
|
rlm@1
|
302
|
rlm@1
|
303 void remoteSendStatus()
|
rlm@1
|
304 {
|
rlm@20
|
305 char buffer[1024];
|
rlm@20
|
306 sprintf(buffer, "T%02x", remoteSignal);
|
rlm@20
|
307 char *s = buffer;
|
rlm@20
|
308 s += 3;
|
rlm@20
|
309 for (int i = 0; i < 15; i++)
|
rlm@20
|
310 {
|
rlm@20
|
311 u32 v = reg[i].I;
|
rlm@20
|
312 sprintf(s, "%02x:%02x%02x%02x%02x;", i,
|
rlm@20
|
313 (v & 255),
|
rlm@20
|
314 (v >> 8) & 255,
|
rlm@20
|
315 (v >> 16) & 255,
|
rlm@20
|
316 (v >> 24) & 255);
|
rlm@20
|
317 s += 12;
|
rlm@20
|
318 }
|
rlm@20
|
319 u32 v = armNextPC;
|
rlm@20
|
320 sprintf(s, "0f:%02x%02x%02x%02x;", (v & 255),
|
rlm@20
|
321 (v >> 8) & 255,
|
rlm@20
|
322 (v >> 16) & 255,
|
rlm@20
|
323 (v >> 24) & 255);
|
rlm@20
|
324 s += 12;
|
rlm@20
|
325 CPUUpdateCPSR();
|
rlm@20
|
326 v = reg[16].I;
|
rlm@20
|
327 sprintf(s, "19:%02x%02x%02x%02x;", (v & 255),
|
rlm@20
|
328 (v >> 8) & 255,
|
rlm@20
|
329 (v >> 16) & 255,
|
rlm@20
|
330 (v >> 24) & 255);
|
rlm@20
|
331 s += 12;
|
rlm@20
|
332 *s = 0;
|
rlm@20
|
333 // printf("Sending %s\n", buffer);
|
rlm@20
|
334 remotePutPacket(buffer);
|
rlm@1
|
335 }
|
rlm@1
|
336
|
rlm@1
|
337 void remoteBinaryWrite(char *p)
|
rlm@1
|
338 {
|
rlm@20
|
339 u32 address;
|
rlm@20
|
340 int count;
|
rlm@20
|
341 sscanf(p, "%x,%x:", &address, &count);
|
rlm@20
|
342 // printf("Binary write for %08x %d\n", address, count);
|
rlm@1
|
343
|
rlm@20
|
344 p = strchr(p, ':');
|
rlm@20
|
345 p++;
|
rlm@20
|
346 for (int i = 0; i < count; i++)
|
rlm@20
|
347 {
|
rlm@20
|
348 u8 b = *p++;
|
rlm@20
|
349 switch (b)
|
rlm@1
|
350 {
|
rlm@20
|
351 case 0x7d:
|
rlm@20
|
352 b = *p++;
|
rlm@20
|
353 debuggerWriteByte(address, (b^0x20));
|
rlm@20
|
354 address++;
|
rlm@20
|
355 break;
|
rlm@20
|
356 default:
|
rlm@20
|
357 debuggerWriteByte(address, b);
|
rlm@20
|
358 address++;
|
rlm@20
|
359 break;
|
rlm@1
|
360 }
|
rlm@20
|
361 }
|
rlm@20
|
362 // printf("ROM is %08x\n", debuggerReadMemory(0x8000254));
|
rlm@20
|
363 remotePutPacket("OK");
|
rlm@1
|
364 }
|
rlm@1
|
365
|
rlm@1
|
366 void remoteMemoryWrite(char *p)
|
rlm@1
|
367 {
|
rlm@20
|
368 u32 address;
|
rlm@20
|
369 int count;
|
rlm@20
|
370 sscanf(p, "%x,%x:", &address, &count);
|
rlm@20
|
371 // printf("Memory write for %08x %d\n", address, count);
|
rlm@1
|
372
|
rlm@20
|
373 p = strchr(p, ':');
|
rlm@20
|
374 p++;
|
rlm@20
|
375 for (int i = 0; i < count; i++)
|
rlm@20
|
376 {
|
rlm@20
|
377 u8 v = 0;
|
rlm@20
|
378 char c = *p++;
|
rlm@20
|
379 if (c <= '9')
|
rlm@20
|
380 v = (c - '0') << 4;
|
rlm@20
|
381 else
|
rlm@20
|
382 v = (c + 10 - 'a') << 4;
|
rlm@20
|
383 c = *p++;
|
rlm@20
|
384 if (c <= '9')
|
rlm@20
|
385 v += (c - '0');
|
rlm@20
|
386 else
|
rlm@20
|
387 v += (c + 10 - 'a');
|
rlm@20
|
388 debuggerWriteByte(address, v);
|
rlm@20
|
389 address++;
|
rlm@20
|
390 }
|
rlm@20
|
391 // printf("ROM is %08x\n", debuggerReadMemory(0x8000254));
|
rlm@20
|
392 remotePutPacket("OK");
|
rlm@1
|
393 }
|
rlm@1
|
394
|
rlm@1
|
395 void remoteMemoryRead(char *p)
|
rlm@1
|
396 {
|
rlm@20
|
397 u32 address;
|
rlm@20
|
398 int count;
|
rlm@20
|
399 sscanf(p, "%x,%x:", &address, &count);
|
rlm@20
|
400 // printf("Memory read for %08x %d\n", address, count);
|
rlm@1
|
401
|
rlm@20
|
402 char buffer[1024];
|
rlm@1
|
403
|
rlm@20
|
404 char *s = buffer;
|
rlm@20
|
405 for (int i = 0; i < count; i++)
|
rlm@20
|
406 {
|
rlm@20
|
407 u8 b = debuggerReadByte(address);
|
rlm@20
|
408 sprintf(s, "%02x", b);
|
rlm@20
|
409 address++;
|
rlm@20
|
410 s += 2;
|
rlm@20
|
411 }
|
rlm@20
|
412 *s = 0;
|
rlm@20
|
413 remotePutPacket(buffer);
|
rlm@1
|
414 }
|
rlm@1
|
415
|
rlm@1
|
416 void remoteStepOverRange(char *p)
|
rlm@1
|
417 {
|
rlm@20
|
418 u32 address;
|
rlm@20
|
419 u32 final;
|
rlm@20
|
420 sscanf(p, "%x,%x", &address, &final);
|
rlm@1
|
421
|
rlm@20
|
422 remotePutPacket("OK");
|
rlm@1
|
423
|
rlm@20
|
424 remoteResumed = true;
|
rlm@20
|
425 do
|
rlm@20
|
426 {
|
rlm@20
|
427 CPULoop(1);
|
rlm@20
|
428 if (debugger)
|
rlm@20
|
429 break;
|
rlm@20
|
430 }
|
rlm@20
|
431 while (armNextPC >= address && armNextPC < final);
|
rlm@1
|
432
|
rlm@20
|
433 remoteResumed = false;
|
rlm@1
|
434
|
rlm@20
|
435 remoteSendStatus();
|
rlm@1
|
436 }
|
rlm@1
|
437
|
rlm@1
|
438 void remoteWriteWatch(char *p, bool active)
|
rlm@1
|
439 {
|
rlm@20
|
440 u32 address;
|
rlm@20
|
441 int count;
|
rlm@20
|
442 sscanf(p, ",%x,%x#", &address, &count);
|
rlm@1
|
443
|
rlm@20
|
444 fprintf(stderr, "Write watch for %08x %d\n", address, count);
|
rlm@1
|
445
|
rlm@20
|
446 if (address < 0x2000000 || address > 0x3007fff)
|
rlm@20
|
447 {
|
rlm@20
|
448 remotePutPacket("E01");
|
rlm@20
|
449 return;
|
rlm@20
|
450 }
|
rlm@1
|
451
|
rlm@20
|
452 if (address > 0x203ffff && address < 0x3000000)
|
rlm@20
|
453 {
|
rlm@20
|
454 remotePutPacket("E01");
|
rlm@20
|
455 return;
|
rlm@20
|
456 }
|
rlm@1
|
457
|
rlm@20
|
458 u32 final = address + count;
|
rlm@1
|
459
|
rlm@20
|
460 if (address < 0x2040000 && final > 0x2040000)
|
rlm@20
|
461 {
|
rlm@20
|
462 remotePutPacket("E01");
|
rlm@20
|
463 return;
|
rlm@20
|
464 }
|
rlm@20
|
465 else if (address < 0x3008000 && final > 0x3008000)
|
rlm@20
|
466 {
|
rlm@20
|
467 remotePutPacket("E01");
|
rlm@20
|
468 return;
|
rlm@20
|
469 }
|
rlm@1
|
470
|
rlm@20
|
471 for (int i = 0; i < count; i++)
|
rlm@20
|
472 {
|
rlm@20
|
473 if ((address >> 24) == 2)
|
rlm@20
|
474 freezeWorkRAM[address & 0x3ffff] = active;
|
rlm@20
|
475 else
|
rlm@20
|
476 freezeInternalRAM[address & 0x7fff] = active;
|
rlm@20
|
477 address++;
|
rlm@20
|
478 }
|
rlm@1
|
479
|
rlm@20
|
480 remotePutPacket("OK");
|
rlm@1
|
481 }
|
rlm@1
|
482
|
rlm@1
|
483 void remoteReadRegisters(char *p)
|
rlm@1
|
484 {
|
rlm@20
|
485 char buffer[1024];
|
rlm@1
|
486
|
rlm@20
|
487 char *s = buffer;
|
rlm@20
|
488 int i;
|
rlm@20
|
489 // regular registers
|
rlm@20
|
490 for (i = 0; i < 15; i++)
|
rlm@20
|
491 {
|
rlm@20
|
492 u32 v = reg[i].I;
|
rlm@20
|
493 sprintf(s, "%02x%02x%02x%02x", v & 255, (v >> 8) & 255,
|
rlm@20
|
494 (v >> 16) & 255, (v >> 24) & 255);
|
rlm@20
|
495 s += 8;
|
rlm@20
|
496 }
|
rlm@20
|
497 // PC
|
rlm@20
|
498 u32 pc = armNextPC;
|
rlm@20
|
499 sprintf(s, "%02x%02x%02x%02x", pc & 255, (pc >> 8) & 255,
|
rlm@20
|
500 (pc >> 16) & 255, (pc >> 24) & 255);
|
rlm@20
|
501 s += 8;
|
rlm@1
|
502
|
rlm@20
|
503 // floating point registers (24-bit)
|
rlm@20
|
504 for (i = 0; i < 8; i++)
|
rlm@20
|
505 {
|
rlm@20
|
506 sprintf(s, "000000000000000000000000");
|
rlm@20
|
507 s += 24;
|
rlm@20
|
508 }
|
rlm@1
|
509
|
rlm@20
|
510 // FP status register
|
rlm@20
|
511 sprintf(s, "00000000");
|
rlm@20
|
512 s += 8;
|
rlm@20
|
513 // CPSR
|
rlm@20
|
514 CPUUpdateCPSR();
|
rlm@20
|
515 u32 v = reg[16].I;
|
rlm@20
|
516 sprintf(s, "%02x%02x%02x%02x", v & 255, (v >> 8) & 255,
|
rlm@20
|
517 (v >> 16) & 255, (v >> 24) & 255);
|
rlm@20
|
518 s += 8;
|
rlm@20
|
519 *s = 0;
|
rlm@20
|
520 remotePutPacket(buffer);
|
rlm@1
|
521 }
|
rlm@1
|
522
|
rlm@1
|
523 void remoteWriteRegister(char *p)
|
rlm@1
|
524 {
|
rlm@20
|
525 int r;
|
rlm@1
|
526
|
rlm@20
|
527 sscanf(p, "%x=", &r);
|
rlm@1
|
528
|
rlm@20
|
529 p = strchr(p, '=');
|
rlm@20
|
530 p++;
|
rlm@1
|
531
|
rlm@20
|
532 char c = *p++;
|
rlm@1
|
533
|
rlm@20
|
534 u32 v = 0;
|
rlm@1
|
535
|
rlm@20
|
536 u8 data[4] = {0, 0, 0, 0};
|
rlm@1
|
537
|
rlm@20
|
538 int i = 0;
|
rlm@1
|
539
|
rlm@20
|
540 while (c != '#')
|
rlm@20
|
541 {
|
rlm@20
|
542 u8 b = 0;
|
rlm@20
|
543 if (c <= '9')
|
rlm@20
|
544 b = (c - '0') << 4;
|
rlm@20
|
545 else
|
rlm@20
|
546 b = (c + 10 - 'a') << 4;
|
rlm@20
|
547 c = *p++;
|
rlm@20
|
548 if (c <= '9')
|
rlm@20
|
549 b += (c - '0');
|
rlm@20
|
550 else
|
rlm@20
|
551 b += (c + 10 - 'a');
|
rlm@20
|
552 data[i++] = b;
|
rlm@20
|
553 c = *p++;
|
rlm@20
|
554 }
|
rlm@1
|
555
|
rlm@20
|
556 v = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
|
rlm@1
|
557
|
rlm@20
|
558 // printf("Write register %d=%08x\n", r, v);
|
rlm@20
|
559 reg[r].I = v;
|
rlm@20
|
560 if (r == 15)
|
rlm@20
|
561 {
|
rlm@20
|
562 armNextPC = v;
|
rlm@20
|
563 if (armState)
|
rlm@20
|
564 reg[15].I = v + 4;
|
rlm@20
|
565 else
|
rlm@20
|
566 reg[15].I = v + 2;
|
rlm@20
|
567 }
|
rlm@20
|
568 remotePutPacket("OK");
|
rlm@1
|
569 }
|
rlm@1
|
570
|
rlm@1
|
571 void remoteStubMain()
|
rlm@1
|
572 {
|
rlm@20
|
573 if (!debugger)
|
rlm@20
|
574 return;
|
rlm@1
|
575
|
rlm@20
|
576 if (remoteResumed)
|
rlm@20
|
577 {
|
rlm@20
|
578 remoteSendStatus();
|
rlm@20
|
579 remoteResumed = false;
|
rlm@20
|
580 }
|
rlm@20
|
581
|
rlm@20
|
582 while (true)
|
rlm@20
|
583 {
|
rlm@20
|
584 char buffer[1024];
|
rlm@20
|
585 int res = remoteRecvFnc(buffer, 1024);
|
rlm@20
|
586
|
rlm@20
|
587 if (res == -1)
|
rlm@1
|
588 {
|
rlm@20
|
589 fprintf(stderr, "GDB connection lost\n");
|
rlm@20
|
590 #ifdef SDL
|
rlm@20
|
591 dbgMain = debuggerMain;
|
rlm@20
|
592 dbgSignal = debuggerSignal;
|
rlm@20
|
593 #endif
|
rlm@20
|
594 debugger = false;
|
rlm@20
|
595 break;
|
rlm@1
|
596 }
|
rlm@1
|
597
|
rlm@20
|
598 // fprintf(stderr, "Received %s\n", buffer);
|
rlm@20
|
599 char *p = buffer;
|
rlm@20
|
600 char c = *p++;
|
rlm@20
|
601 char pp = '+';
|
rlm@20
|
602 remoteSendFnc(&pp, 1);
|
rlm@20
|
603
|
rlm@20
|
604 if (c != '$')
|
rlm@20
|
605 continue;
|
rlm@20
|
606 c = *p++;
|
rlm@20
|
607 switch (c)
|
rlm@1
|
608 {
|
rlm@20
|
609 case '?':
|
rlm@20
|
610 remoteSendSignal();
|
rlm@20
|
611 break;
|
rlm@20
|
612 case 'D':
|
rlm@20
|
613 remotePutPacket("OK");
|
rlm@1
|
614 #ifdef SDL
|
rlm@20
|
615 dbgMain = debuggerMain;
|
rlm@20
|
616 dbgSignal = debuggerSignal;
|
rlm@1
|
617 #endif
|
rlm@20
|
618 remoteResumed = true;
|
rlm@20
|
619 debugger = false;
|
rlm@20
|
620 return;
|
rlm@20
|
621 case 'e':
|
rlm@20
|
622 remoteStepOverRange(p);
|
rlm@20
|
623 break;
|
rlm@20
|
624 case 'k':
|
rlm@20
|
625 remotePutPacket("OK");
|
rlm@1
|
626 #ifdef SDL
|
rlm@20
|
627 dbgMain = debuggerMain;
|
rlm@20
|
628 dbgSignal = debuggerSignal;
|
rlm@1
|
629 #endif
|
rlm@20
|
630 debugger = false;
|
rlm@20
|
631 emulating = false;
|
rlm@20
|
632 return;
|
rlm@20
|
633 case 'C':
|
rlm@20
|
634 remoteResumed = true;
|
rlm@20
|
635 debugger = false;
|
rlm@20
|
636 return;
|
rlm@20
|
637 case 'c':
|
rlm@20
|
638 remoteResumed = true;
|
rlm@20
|
639 debugger = false;
|
rlm@20
|
640 return;
|
rlm@20
|
641 case 's':
|
rlm@20
|
642 remoteResumed = true;
|
rlm@20
|
643 remoteSignal = 5;
|
rlm@20
|
644 CPULoop(1);
|
rlm@20
|
645 if (remoteResumed)
|
rlm@20
|
646 {
|
rlm@20
|
647 remoteResumed = false;
|
rlm@20
|
648 remoteSendStatus();
|
rlm@20
|
649 }
|
rlm@20
|
650 break;
|
rlm@20
|
651 case 'g':
|
rlm@20
|
652 remoteReadRegisters(p);
|
rlm@20
|
653 break;
|
rlm@20
|
654 case 'P':
|
rlm@20
|
655 remoteWriteRegister(p);
|
rlm@20
|
656 break;
|
rlm@20
|
657 case 'M':
|
rlm@20
|
658 remoteMemoryWrite(p);
|
rlm@20
|
659 break;
|
rlm@20
|
660 case 'm':
|
rlm@20
|
661 remoteMemoryRead(p);
|
rlm@20
|
662 break;
|
rlm@20
|
663 case 'X':
|
rlm@20
|
664 remoteBinaryWrite(p);
|
rlm@20
|
665 break;
|
rlm@20
|
666 case 'H':
|
rlm@20
|
667 remotePutPacket("OK");
|
rlm@20
|
668 break;
|
rlm@20
|
669 case 'q':
|
rlm@20
|
670 remotePutPacket("");
|
rlm@20
|
671 break;
|
rlm@20
|
672 case 'Z':
|
rlm@20
|
673 if (*p++ == '2')
|
rlm@20
|
674 {
|
rlm@20
|
675 remoteWriteWatch(p, true);
|
rlm@20
|
676 }
|
rlm@20
|
677 else
|
rlm@20
|
678 remotePutPacket("");
|
rlm@20
|
679 break;
|
rlm@20
|
680 case 'z':
|
rlm@20
|
681 if (*p++ == '2')
|
rlm@20
|
682 {
|
rlm@20
|
683 remoteWriteWatch(p, false);
|
rlm@20
|
684 }
|
rlm@20
|
685 else
|
rlm@20
|
686 remotePutPacket("");
|
rlm@20
|
687 break;
|
rlm@20
|
688 default:
|
rlm@20
|
689 {
|
rlm@20
|
690 *(strchr(p, '#') + 3) = 0;
|
rlm@20
|
691 fprintf(stderr, "Unknown packet %s\n", --p);
|
rlm@20
|
692 remotePutPacket("");
|
rlm@20
|
693 break;
|
rlm@20
|
694 }
|
rlm@1
|
695 }
|
rlm@20
|
696 }
|
rlm@1
|
697 }
|
rlm@1
|
698
|
rlm@1
|
699 void remoteStubSignal(int sig, int number)
|
rlm@1
|
700 {
|
rlm@20
|
701 remoteSignal = sig;
|
rlm@20
|
702 remoteResumed = false;
|
rlm@20
|
703 remoteSendStatus();
|
rlm@20
|
704 debugger = true;
|
rlm@1
|
705 }
|
rlm@1
|
706
|
rlm@1
|
707 void remoteCleanUp()
|
rlm@1
|
708 {
|
rlm@20
|
709 if (remoteCleanUpFnc)
|
rlm@20
|
710 remoteCleanUpFnc();
|
rlm@1
|
711 }
|
rlm@1
|
712
|