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