all repos — mgba @ fcc8b5c8052ae6bd4b4e7931ceb60461cee69605

mGBA Game Boy Advance Emulator

src/debugger/gdb-stub.c (view raw)

  1/* Copyright (c) 2013-2016 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include <mgba/internal/debugger/gdb-stub.h>
  7
  8#include <mgba/core/core.h>
  9#include <mgba/internal/arm/debugger/debugger.h>
 10#include <mgba/internal/arm/isa-inlines.h>
 11#include <mgba/internal/gba/memory.h>
 12
 13#include <signal.h>
 14
 15#ifndef SIGTRAP
 16#define SIGTRAP 5 /* Win32 Signals do not include SIGTRAP */
 17#endif
 18
 19#define SOCKET_TIMEOUT 50
 20
 21enum GDBError {
 22	GDB_NO_ERROR = 0x00,
 23	GDB_BAD_ARGUMENTS = 0x06,
 24	GDB_UNSUPPORTED_COMMAND = 0x07
 25};
 26
 27enum {
 28	MACH_O_ARM = 12,
 29	MACH_O_ARM_V4T = 5
 30};
 31
 32static void _sendMessage(struct GDBStub* stub);
 33
 34static void _gdbStubDeinit(struct mDebugger* debugger) {
 35	struct GDBStub* stub = (struct GDBStub*) debugger;
 36	if (!SOCKET_FAILED(stub->socket)) {
 37		GDBStubShutdown(stub);
 38	}
 39}
 40
 41static void _gdbStubEntered(struct mDebugger* debugger, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
 42	struct GDBStub* stub = (struct GDBStub*) debugger;
 43	switch (reason) {
 44	case DEBUGGER_ENTER_MANUAL:
 45		snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02x", SIGINT);
 46		break;
 47	case DEBUGGER_ENTER_BREAKPOINT:
 48		if (stub->supportsHwbreak && stub->supportsSwbreak && info) {
 49			snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "T%02x%cwbreak:;", SIGTRAP, info->breakType == BREAKPOINT_SOFTWARE ? 's' : 'h');
 50		} else {
 51			snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02xk", SIGTRAP);
 52		}
 53		break;
 54	case DEBUGGER_ENTER_WATCHPOINT:
 55		if (info) {
 56			const char* type = 0;
 57			switch (info->watchType) {
 58			case WATCHPOINT_WRITE:
 59				if (info->newValue == info->oldValue) {
 60					if (stub->d.state == DEBUGGER_PAUSED) {
 61						stub->d.state = DEBUGGER_RUNNING;
 62					}
 63					return;
 64				}
 65				type = "watch";
 66				break;
 67			case WATCHPOINT_READ:
 68				type = "rwatch";
 69				break;
 70			case WATCHPOINT_RW:
 71				type = "awatch";
 72				break;
 73			}
 74			snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "T%02x%s:%08x;", SIGTRAP, type, info->address);
 75		} else {
 76			snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02x", SIGTRAP);
 77		}
 78		break;
 79	case DEBUGGER_ENTER_ILLEGAL_OP:
 80		snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02x", SIGILL);
 81		break;
 82	case DEBUGGER_ENTER_ATTACHED:
 83		return;
 84	}
 85	_sendMessage(stub);
 86}
 87
 88static void _gdbStubPoll(struct mDebugger* debugger) {
 89	struct GDBStub* stub = (struct GDBStub*) debugger;
 90	--stub->untilPoll;
 91	if (stub->untilPoll > 0) {
 92		return;
 93	}
 94	stub->untilPoll = GDB_STUB_INTERVAL;
 95	stub->shouldBlock = false;
 96	GDBStubUpdate(stub);
 97}
 98
 99static void _gdbStubWait(struct mDebugger* debugger) {
100	struct GDBStub* stub = (struct GDBStub*) debugger;
101	stub->shouldBlock = true;
102	GDBStubUpdate(stub);
103}
104
105static void _ack(struct GDBStub* stub) {
106	char ack = '+';
107	SocketSend(stub->connection, &ack, 1);
108}
109
110static void _nak(struct GDBStub* stub) {
111	char nak = '-';
112	mLOG(DEBUGGER, WARN, "Packet error");
113	SocketSend(stub->connection, &nak, 1);
114}
115
116static uint32_t _hex2int(const char* hex, int maxDigits) {
117	uint32_t value = 0;
118	uint8_t letter;
119
120	while (maxDigits--) {
121		letter = *hex - '0';
122		if (letter > 9) {
123			letter = *hex - 'a';
124			if (letter > 5) {
125				break;
126			}
127			value *= 0x10;
128			value += letter + 10;
129		} else {
130			value *= 0x10;
131			value += letter;
132		}
133		++hex;
134	}
135	return value;
136}
137
138static void _int2hex8(uint8_t value, char* out) {
139	static const char language[] = "0123456789abcdef";
140	out[0] = language[value >> 4];
141	out[1] = language[value & 0xF];
142}
143
144static void _int2hex32(uint32_t value, char* out) {
145	static const char language[] = "0123456789abcdef";
146	out[6] = language[value >> 28];
147	out[7] = language[(value >> 24) & 0xF];
148	out[4] = language[(value >> 20) & 0xF];
149	out[5] = language[(value >> 16) & 0xF];
150	out[2] = language[(value >> 12) & 0xF];
151	out[3] = language[(value >> 8) & 0xF];
152	out[0] = language[(value >> 4) & 0xF];
153	out[1] = language[value & 0xF];
154}
155
156static uint32_t _readHex(const char* in, unsigned* out) {
157	unsigned i;
158	for (i = 0; i < 8; ++i) {
159		if (in[i] == ',' || in[i] == ':' || in[i] == '=') {
160			break;
161		}
162	}
163	*out += i;
164	return _hex2int(in, i);
165}
166
167static void _sendMessage(struct GDBStub* stub) {
168	if (stub->lineAck != GDB_ACK_OFF) {
169		stub->lineAck = GDB_ACK_PENDING;
170	}
171	uint8_t checksum = 0;
172	int i = 1;
173	char buffer = stub->outgoing[0];
174	char swap;
175	stub->outgoing[0] = '$';
176	if (buffer) {
177		for (; i < GDB_STUB_MAX_LINE - 5; ++i) {
178			checksum += buffer;
179			swap = stub->outgoing[i];
180			stub->outgoing[i] = buffer;
181			buffer = swap;
182			if (!buffer) {
183				++i;
184				break;
185			}
186		}
187	}
188	stub->outgoing[i] = '#';
189	_int2hex8(checksum, &stub->outgoing[i + 1]);
190	stub->outgoing[i + 3] = 0;
191	mLOG(DEBUGGER, DEBUG, "> %s", stub->outgoing);
192	SocketSend(stub->connection, stub->outgoing, i + 3);
193}
194
195static void _error(struct GDBStub* stub, enum GDBError error) {
196	snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "E%02x", error);
197	_sendMessage(stub);
198}
199
200static void _writeHostInfo(struct GDBStub* stub) {
201	snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "cputype:%u;cpusubtype:%u:ostype:none;vendor:none;endian:little;ptrsize:4;", MACH_O_ARM, MACH_O_ARM_V4T);
202	_sendMessage(stub);
203}
204
205static void _continue(struct GDBStub* stub, const char* message) {
206	stub->d.state = DEBUGGER_CUSTOM;
207	stub->untilPoll = GDB_STUB_INTERVAL;
208	// TODO: parse message
209	UNUSED(message);
210}
211
212static void _step(struct GDBStub* stub, const char* message) {
213	stub->d.core->step(stub->d.core);
214	snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02x", SIGTRAP);
215	_sendMessage(stub);
216	// TODO: parse message
217	UNUSED(message);
218}
219
220static void _writeMemoryBinary(struct GDBStub* stub, const char* message) {
221	const char* readAddress = message;
222	unsigned i = 0;
223	uint32_t address = _readHex(readAddress, &i);
224	readAddress += i + 1;
225
226	i = 0;
227	uint32_t size = _readHex(readAddress, &i);
228	readAddress += i + 1;
229
230	if (size > 512) {
231		_error(stub, GDB_BAD_ARGUMENTS);
232		return;
233	}
234
235	struct ARMCore* cpu = stub->d.core->cpu;
236	for (i = 0; i < size; i++) {
237		uint8_t byte = *readAddress;
238		++readAddress;
239
240		// Parse escape char
241		if (byte == 0x7D) {
242			byte = *readAddress ^ 0x20;
243			++readAddress;
244		}
245
246		GBAPatch8(cpu, address + i, byte, 0);
247	}
248
249	strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4);
250	_sendMessage(stub);
251}
252
253
254static void _writeMemory(struct GDBStub* stub, const char* message) {
255	const char* readAddress = message;
256	unsigned i = 0;
257	uint32_t address = _readHex(readAddress, &i);
258	readAddress += i + 1;
259
260	i = 0;
261	uint32_t size = _readHex(readAddress, &i);
262	readAddress += i + 1;
263
264	if (size > 512) {
265		_error(stub, GDB_BAD_ARGUMENTS);
266		return;
267	}
268
269	struct ARMCore* cpu = stub->d.core->cpu;
270	for (i = 0; i < size; ++i, readAddress += 2) {
271		uint8_t byte = _hex2int(readAddress, 2);
272		GBAPatch8(cpu, address + i, byte, 0);
273	}
274
275	strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4);
276	_sendMessage(stub);
277}
278
279static void _readMemory(struct GDBStub* stub, const char* message) {
280	const char* readAddress = message;
281	unsigned i = 0;
282	uint32_t address = _readHex(readAddress, &i);
283	readAddress += i + 1;
284	uint32_t size = _readHex(readAddress, &i);
285	if (size > 512) {
286		_error(stub, GDB_BAD_ARGUMENTS);
287		return;
288	}
289	struct ARMCore* cpu = stub->d.core->cpu;
290	int writeAddress = 0;
291	for (i = 0; i < size; ++i, writeAddress += 2) {
292		uint8_t byte = cpu->memory.load8(cpu, address + i, 0);
293		_int2hex8(byte, &stub->outgoing[writeAddress]);
294	}
295	stub->outgoing[writeAddress] = 0;
296	_sendMessage(stub);
297}
298
299static void _writeGPRs(struct GDBStub* stub, const char* message) {
300	struct ARMCore* cpu = stub->d.core->cpu;
301	const char* readAddress = message;
302
303	int r;
304	for (r = 0; r <= ARM_PC; ++r) {
305		cpu->gprs[r] = _hex2int(readAddress, 8);
306		readAddress += 8;
307	}
308	int32_t currentCycles = 0;
309	if (cpu->executionMode == MODE_ARM) {
310		ARM_WRITE_PC;
311	} else {
312		THUMB_WRITE_PC;
313	}
314
315	strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4);
316	_sendMessage(stub);
317}
318
319static void _readGPRs(struct GDBStub* stub, const char* message) {
320	struct ARMCore* cpu = stub->d.core->cpu;
321	UNUSED(message);
322	int r;
323	int i = 0;
324
325	// General purpose registers
326	for (r = 0; r < ARM_PC; ++r) {
327		_int2hex32(cpu->gprs[r], &stub->outgoing[i]);
328		i += 8;
329	}
330
331	// Program counter
332	_int2hex32(cpu->gprs[ARM_PC] - (cpu->cpsr.t ? WORD_SIZE_THUMB : WORD_SIZE_ARM), &stub->outgoing[i]);
333	i += 8;
334
335	// Floating point registers, unused on the GBA (8 of them, 24 bits each)
336	for (r = 0; r < 8 * 3; ++r) {
337		_int2hex32(0, &stub->outgoing[i]);
338		i += 8;
339	}
340
341	// Floating point status, unused on the GBA (32 bits)
342	_int2hex32(0, &stub->outgoing[i]);
343	i += 8;
344
345	// CPU status
346	_int2hex32(cpu->cpsr.packed, &stub->outgoing[i]);
347	i += 8;
348
349	stub->outgoing[i] = 0;
350	_sendMessage(stub);
351}
352
353static void _writeRegister(struct GDBStub* stub, const char* message) {
354	struct ARMCore* cpu = stub->d.core->cpu;
355	const char* readAddress = message;
356
357	unsigned i = 0;
358	uint32_t reg = _readHex(readAddress, &i);
359	readAddress += i + 1;
360
361	uint32_t value = _readHex(readAddress, &i);
362
363#ifdef _MSC_VER
364	value = _byteswap_ulong(value);
365#else
366	value = __builtin_bswap32(value);
367#endif
368
369	if (reg <= ARM_PC) {
370		cpu->gprs[reg] = value;
371		if (reg == ARM_PC) {
372			int32_t currentCycles = 0;
373			if (cpu->executionMode == MODE_ARM) {
374				ARM_WRITE_PC;
375			} else {
376				THUMB_WRITE_PC;
377			}
378		}
379	} else if (reg == 0x19) {
380		cpu->cpsr.packed = value;
381	} else {
382		stub->outgoing[0] = '\0';
383		_sendMessage(stub);
384		return;
385	}
386
387	strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4);
388	_sendMessage(stub);
389}
390
391static void _readRegister(struct GDBStub* stub, const char* message) {
392	struct ARMCore* cpu = stub->d.core->cpu;
393	const char* readAddress = message;
394	unsigned i = 0;
395	uint32_t reg = _readHex(readAddress, &i);
396	uint32_t value;
397	if (reg < 0x10) {
398		value = cpu->gprs[reg];
399	} else if (reg == 0x19) {
400		value = cpu->cpsr.packed;
401	} else {
402		stub->outgoing[0] = '\0';
403		_sendMessage(stub);
404		return;
405	}
406	_int2hex32(value, stub->outgoing);
407	stub->outgoing[8] = '\0';
408	_sendMessage(stub);
409}
410
411static void _processQSupportedCommand(struct GDBStub* stub, const char* message) {
412	const char* terminator = strrchr(message, '#');
413	stub->supportsSwbreak = false;
414	stub->supportsHwbreak = false;
415	while (message < terminator) {
416		const char* end = strchr(message, ';');
417		size_t len;
418		if (end && end < terminator) {
419			len = end - message;
420		} else {
421			len = terminator - message;
422		}
423		if (!strncmp(message, "swbreak+", len)) {
424			stub->supportsSwbreak = true;
425		} else if (!strncmp(message, "hwbreak+", len)) {
426			stub->supportsHwbreak = true;
427		} else if (!strncmp(message, "swbreak-", len)) {
428			stub->supportsSwbreak = false;
429		} else if (!strncmp(message, "hwbreak-", len)) {
430			stub->supportsHwbreak = false;
431		}
432		if (!end) {
433			break;
434		}
435		message = end + 1;
436	}
437	strncpy(stub->outgoing, "swbreak+;hwbreak+", GDB_STUB_MAX_LINE - 4);
438}
439
440static void _processQReadCommand(struct GDBStub* stub, const char* message) {
441	stub->outgoing[0] = '\0';
442	if (!strncmp("HostInfo#", message, 9)) {
443		_writeHostInfo(stub);
444		return;
445	}
446	if (!strncmp("Attached#", message, 9)) {
447		strncpy(stub->outgoing, "1", GDB_STUB_MAX_LINE - 4);
448	} else if (!strncmp("VAttachOrWaitSupported#", message, 23)) {
449		strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4);
450	} else if (!strncmp("C#", message, 2)) {
451		strncpy(stub->outgoing, "QC1", GDB_STUB_MAX_LINE - 4);
452	} else if (!strncmp("fThreadInfo#", message, 12)) {
453		strncpy(stub->outgoing, "m1", GDB_STUB_MAX_LINE - 4);
454	} else if (!strncmp("sThreadInfo#", message, 12)) {
455		strncpy(stub->outgoing, "l", GDB_STUB_MAX_LINE - 4);
456	} else if (!strncmp("Supported:", message, 10)) {
457		_processQSupportedCommand(stub, message + 10);
458	}
459	_sendMessage(stub);
460}
461
462static void _processQWriteCommand(struct GDBStub* stub, const char* message) {
463	stub->outgoing[0] = '\0';
464	if (!strncmp("StartNoAckMode#", message, 16)) {
465		stub->lineAck = GDB_ACK_OFF;
466		strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4);
467	}
468	_sendMessage(stub);
469}
470
471static void _processVWriteCommand(struct GDBStub* stub, const char* message) {
472	UNUSED(message);
473	stub->outgoing[0] = '\0';
474	_sendMessage(stub);
475}
476
477static void _processVReadCommand(struct GDBStub* stub, const char* message) {
478	stub->outgoing[0] = '\0';
479	if (!strncmp("Attach", message, 6)) {
480		strncpy(stub->outgoing, "1", GDB_STUB_MAX_LINE - 4);
481		mDebuggerEnter(&stub->d, DEBUGGER_ENTER_MANUAL, 0);
482	}
483	_sendMessage(stub);
484}
485
486static void _setBreakpoint(struct GDBStub* stub, const char* message) {
487	const char* readAddress = &message[2];
488	unsigned i = 0;
489	uint32_t address = _readHex(readAddress, &i);
490	readAddress += i + 1;
491	uint32_t kind = _readHex(readAddress, &i);
492
493	switch (message[0]) {
494	case '0':
495		ARMDebuggerSetSoftwareBreakpoint(stub->d.platform, address, kind == 2 ? MODE_THUMB : MODE_ARM);
496		break;
497	case '1':
498		stub->d.platform->setBreakpoint(stub->d.platform, address, -1);
499		break;
500	case '2':
501		stub->d.platform->setWatchpoint(stub->d.platform, address, WATCHPOINT_WRITE);
502		break;
503	case '3':
504		stub->d.platform->setWatchpoint(stub->d.platform, address, WATCHPOINT_READ);
505		break;
506	case '4':
507		stub->d.platform->setWatchpoint(stub->d.platform, address, WATCHPOINT_RW);
508		break;
509	default:
510		stub->outgoing[0] = '\0';
511		_sendMessage(stub);
512		return;
513	}
514	strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4);
515	_sendMessage(stub);
516}
517
518static void _clearBreakpoint(struct GDBStub* stub, const char* message) {
519	const char* readAddress = &message[2];
520	unsigned i = 0;
521	uint32_t address = _readHex(readAddress, &i);
522	switch (message[0]) {
523	case '0':
524		ARMDebuggerClearSoftwareBreakpoint(stub->d.platform, address);
525		break;
526	case '1':
527		stub->d.platform->clearBreakpoint(stub->d.platform, address, -1);
528		break;
529	case '2':
530	case '3':
531	case '4':
532		stub->d.platform->clearWatchpoint(stub->d.platform, address);
533		break;
534	default:
535		break;
536	}
537	strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4);
538	_sendMessage(stub);
539}
540
541size_t _parseGDBMessage(struct GDBStub* stub, const char* message) {
542	uint8_t checksum = 0;
543	int parsed = 1;
544	switch (*message) {
545	case '+':
546		stub->lineAck = GDB_ACK_RECEIVED;
547		return parsed;
548	case '-':
549		stub->lineAck = GDB_NAK_RECEIVED;
550		return parsed;
551	case '$':
552		++message;
553		break;
554	case '\x03':
555		mDebuggerEnter(&stub->d, DEBUGGER_ENTER_MANUAL, 0);
556		return parsed;
557	default:
558		_nak(stub);
559		return parsed;
560	}
561
562	int i;
563	char messageType = message[0];
564	for (i = 0; message[i] != '#'; ++i, ++parsed) {
565		checksum += message[i];
566	}
567	if (!message[i]) {
568		_nak(stub);
569		return parsed;
570	}
571	++i;
572	++parsed;
573	if (!message[i]) {
574		_nak(stub);
575		return parsed;
576	} else if (!message[i + 1]) {
577		++parsed;
578		_nak(stub);
579		return parsed;
580	}
581	parsed += 2;
582	int networkChecksum = _hex2int(&message[i], 2);
583	if (networkChecksum != checksum) {
584		mLOG(DEBUGGER, WARN, "Checksum error: expected %02x, got %02x", checksum, networkChecksum);
585		_nak(stub);
586		return parsed;
587	}
588
589	_ack(stub);
590	++message;
591	switch (messageType) {
592	case '?':
593		snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02x", SIGINT);
594		_sendMessage(stub);
595		break;
596	case 'c':
597		_continue(stub, message);
598		break;
599	case 'G':
600		_writeGPRs(stub, message);
601		break;
602	case 'g':
603		_readGPRs(stub, message);
604		break;
605	case 'H':
606		// This is faked because we only have one thread
607		strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4);
608		_sendMessage(stub);
609		break;
610	case 'M':
611		_writeMemory(stub, message);
612		break;
613	case 'm':
614		_readMemory(stub, message);
615		break;
616	case 'P':
617		_writeRegister(stub, message);
618		break;
619	case 'p':
620		_readRegister(stub, message);
621		break;
622	case 'Q':
623		_processQWriteCommand(stub, message);
624		break;
625	case 'q':
626		_processQReadCommand(stub, message);
627		break;
628	case 's':
629		_step(stub, message);
630		break;
631	case 'V':
632		_processVWriteCommand(stub, message);
633		break;
634	case 'v':
635		_processVReadCommand(stub, message);
636		break;
637	case 'X':
638		_writeMemoryBinary(stub, message);
639                break;
640	case 'Z':
641		_setBreakpoint(stub, message);
642		break;
643	case 'z':
644		_clearBreakpoint(stub, message);
645		break;
646	default:
647		_error(stub, GDB_UNSUPPORTED_COMMAND);
648		break;
649	}
650	return parsed;
651}
652
653void GDBStubCreate(struct GDBStub* stub) {
654	stub->socket = INVALID_SOCKET;
655	stub->connection = INVALID_SOCKET;
656	stub->d.init = 0;
657	stub->d.deinit = _gdbStubDeinit;
658	stub->d.paused = _gdbStubWait;
659	stub->d.entered = _gdbStubEntered;
660	stub->d.custom = _gdbStubPoll;
661	stub->untilPoll = GDB_STUB_INTERVAL;
662	stub->lineAck = GDB_ACK_PENDING;
663	stub->shouldBlock = false;
664}
665
666bool GDBStubListen(struct GDBStub* stub, int port, const struct Address* bindAddress) {
667	if (!SOCKET_FAILED(stub->socket)) {
668		GDBStubShutdown(stub);
669	}
670	stub->socket = SocketOpenTCP(port, bindAddress);
671	if (SOCKET_FAILED(stub->socket)) {
672		mLOG(DEBUGGER, ERROR, "Couldn't open socket");
673		return false;
674	}
675	if (!SocketSetBlocking(stub->socket, false)) {
676		goto cleanup;
677	}
678	int err = SocketListen(stub->socket, 1);
679	if (err) {
680		goto cleanup;
681	}
682
683	return true;
684
685cleanup:
686	mLOG(DEBUGGER, ERROR, "Couldn't listen on port");
687	SocketClose(stub->socket);
688	stub->socket = INVALID_SOCKET;
689	return false;
690}
691
692void GDBStubHangup(struct GDBStub* stub) {
693	if (!SOCKET_FAILED(stub->connection)) {
694		SocketClose(stub->connection);
695		stub->connection = INVALID_SOCKET;
696	}
697	if (stub->d.state == DEBUGGER_PAUSED) {
698		stub->d.state = DEBUGGER_RUNNING;
699	}
700}
701
702void GDBStubShutdown(struct GDBStub* stub) {
703	GDBStubHangup(stub);
704	if (!SOCKET_FAILED(stub->socket)) {
705		SocketClose(stub->socket);
706		stub->socket = INVALID_SOCKET;
707	}
708}
709
710void GDBStubUpdate(struct GDBStub* stub) {
711	if (stub->socket == INVALID_SOCKET) {
712		if (stub->d.state == DEBUGGER_PAUSED) {
713			stub->d.state = DEBUGGER_RUNNING;
714		}
715		return;
716	}
717	if (stub->connection == INVALID_SOCKET) {
718		if (stub->shouldBlock) {
719			Socket reads = stub->socket;
720			SocketPoll(1, &reads, 0, 0, SOCKET_TIMEOUT);
721		}
722		stub->connection = SocketAccept(stub->socket, 0);
723		if (!SOCKET_FAILED(stub->connection)) {
724			if (!SocketSetBlocking(stub->connection, false)) {
725				goto connectionLost;
726			}
727			mDebuggerEnter(&stub->d, DEBUGGER_ENTER_ATTACHED, 0);
728		} else if (SocketWouldBlock()) {
729			return;
730		} else {
731			goto connectionLost;
732		}
733	}
734	while (true) {
735		if (stub->shouldBlock) {
736			Socket reads = stub->connection;
737			SocketPoll(1, &reads, 0, 0, SOCKET_TIMEOUT);
738		}
739		ssize_t messageLen = SocketRecv(stub->connection, stub->line, GDB_STUB_MAX_LINE - 1);
740		if (messageLen == 0) {
741			goto connectionLost;
742		}
743		if (messageLen == -1) {
744			if (SocketWouldBlock()) {
745				return;
746			}
747			goto connectionLost;
748		}
749		stub->line[messageLen] = '\0';
750		mLOG(DEBUGGER, DEBUG, "< %s", stub->line);
751		ssize_t position = 0;
752		while (position < messageLen) {
753			position += _parseGDBMessage(stub, &stub->line[position]);
754		}
755	}
756
757connectionLost:
758	mLOG(DEBUGGER, WARN, "Connection lost");
759	GDBStubHangup(stub);
760}