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