idevicedebugserverproxy: Add support for 'qLaunchGDBServer' command of lldb
diff --git a/docs/idevicedebugserverproxy.1 b/docs/idevicedebugserverproxy.1
index 248c694..69200ee 100644
--- a/docs/idevicedebugserverproxy.1
+++ b/docs/idevicedebugserverproxy.1
@@ -22,6 +22,9 @@
 .B \-n, \-\-network
 connect to network device.
 .TP
+.B \-l, \-\-lldb
+Enable lldb support.
+.TP
 .B \-d, \-\-debug
 enable communication debugging.
 .TP
diff --git a/tools/idevicedebugserverproxy.c b/tools/idevicedebugserverproxy.c
index 8a3b4ff..9fe7051 100644
--- a/tools/idevicedebugserverproxy.c
+++ b/tools/idevicedebugserverproxy.c
@@ -52,8 +52,10 @@
 #define info(...) fprintf(stdout, __VA_ARGS__); fflush(stdout)
 #define debug(...) if(debug_mode) fprintf(stdout, __VA_ARGS__)
 
+static int support_lldb = 0;
 static int debug_mode = 0;
 static int quit_flag = 0;
+static uint16_t local_port = 0;
 
 typedef struct {
 	int client_fd;
@@ -90,6 +92,7 @@
 		"  -u, --udid UDID       target specific device by UDID\n"
 		"  -n, --network         connect to network device\n"
 		"  -d, --debug           enable communication debugging\n"
+		"  -l, --lldb            enable lldb support\n"
 		"  -h, --help            prints usage information\n"
 		"  -v, --version         prints version information\n"
 		"\n"
@@ -98,6 +101,26 @@
 	);
 }
 
+static int intercept_packet(char *packet, ssize_t *packet_len) {
+	static const char kReqLaunchServer[] = "$qLaunchGDBServer;#4b";
+
+	char buffer[64] = {0};
+	if (*packet_len == (ssize_t)(sizeof(kReqLaunchServer) - 1)
+		&& memcmp(packet, kReqLaunchServer, sizeof(kReqLaunchServer) - 1) == 0) {
+		sprintf(buffer, "port:%d;", local_port);
+	} else {
+		return 0;
+	}
+	int sum = 0;
+	for (size_t i = 0; i < strlen(buffer); i++) {
+		sum += buffer[i];
+	}
+	sum = sum & 255;
+	sprintf(packet, "$%s#%02x", buffer, sum);
+	*packet_len = strlen(packet);
+	return 1;
+}
+
 static void* connection_handler(void* data)
 {
 	debugserver_error_t derr = DEBUGSERVER_E_SUCCESS;
@@ -137,7 +160,10 @@
 				fprintf(stderr, "connection closed\n");
 				break;
 			}
-
+			if (support_lldb && intercept_packet(buf, &n)) {
+				socket_send(client_fd, buf, n);
+				continue;
+			}
 			uint32_t sent = 0;
 			debugserver_client_send(socket_info->debugserver_client, buf, n, &sent);
 		}
@@ -180,7 +206,6 @@
 	thread_info_t *thread_list = NULL;
 	const char* udid = NULL;
 	int use_network = 0;
-	uint16_t local_port = 0;
 	int server_fd;
 	int result = EXIT_SUCCESS;
 	int c = 0;
@@ -189,6 +214,7 @@
 		{ "help", no_argument, NULL, 'h' },
 		{ "udid", required_argument, NULL, 'u' },
 		{ "network", no_argument, NULL, 'n' },
+		{ "lldb", no_argument, NULL, 'l' },
 		{ "version", no_argument, NULL, 'v' },
 		{ NULL, 0, NULL, 0}
 	};
@@ -234,6 +260,9 @@
 		case 'n':
 			use_network = 1;
 			break;
+		case 'l':
+			support_lldb = 1;
+			break;
 		case 'h':
 			print_usage(argc, argv, 0);
 			return 0;