1 /*
2  * Copyright (c) 2020 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <device.h>
8 #include <kernel.h>
9 
10 #include <logging/log.h>
11 LOG_MODULE_REGISTER(gdbstub);
12 
13 #include <sys/util.h>
14 
15 #include <ctype.h>
16 #include <stdbool.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/types.h>
21 
22 #include "gdbstub_backend.h"
23 
24 #define GDB_PACKET_SIZE 256
25 
26 /* GDB remote serial protocol does not define errors value properly
27  * and handle all error packets as the same the code error is not
28  * used. There are informal values used by others gdbstub
29  * implementation, like qemu. Lets use the same here.
30  */
31 #define GDB_ERROR_GENERAL   "E01"
32 #define GDB_ERROR_MEMORY    "E14"
33 #define GDB_ERROR_OVERFLOW  "E22"
34 
35 /**
36  * Add preamble and termination to the given data.
37  *
38  * It returns 0 if the packet was acknowledge, -1 otherwise.
39  */
gdb_send_packet(const uint8_t * data,size_t len)40 static int gdb_send_packet(const uint8_t *data, size_t len)
41 {
42 	uint8_t buf[2];
43 	uint8_t checksum = 0;
44 
45 	/* Send packet start */
46 	z_gdb_putchar('$');
47 
48 	/* Send packet data and calculate checksum */
49 	while (len-- > 0) {
50 		checksum += *data;
51 		z_gdb_putchar(*data++);
52 	}
53 
54 	/* Send the checksum */
55 	z_gdb_putchar('#');
56 
57 	if (bin2hex(&checksum, 1, buf, sizeof(buf)) == 0) {
58 		return -1;
59 	}
60 
61 	z_gdb_putchar(buf[0]);
62 	z_gdb_putchar(buf[1]);
63 
64 	if (z_gdb_getchar() == '+') {
65 		return 0;
66 	}
67 
68 	/* Just got an invalid response */
69 	return -1;
70 }
71 
72 /**
73  * Receives a packet
74  *
75  * Return 0 in case of success, otherwise -1
76  */
gdb_get_packet(uint8_t * buf,size_t buf_len,size_t * len)77 static int gdb_get_packet(uint8_t *buf, size_t buf_len, size_t *len)
78 {
79 	uint8_t ch = '0';
80 	uint8_t expected_checksum, checksum = 0;
81 	uint8_t checksum_buf[2];
82 
83 	/* Wait for packet start */
84 	checksum = 0;
85 
86 	/* wait for the start character, ignore the rest */
87 	while (ch != '$') {
88 		ch = z_gdb_getchar();
89 	}
90 
91 	*len = 0;
92 	/* Read until receive # or the end of the buffer */
93 	while (*len < (buf_len - 1)) {
94 		ch = z_gdb_getchar();
95 
96 		if (ch == '#') {
97 			break;
98 		}
99 
100 		checksum += ch;
101 		buf[*len] = ch;
102 		(*len)++;
103 	}
104 
105 	buf[*len] = '\0';
106 
107 	/* Get checksum now */
108 	checksum_buf[0] = z_gdb_getchar();
109 	checksum_buf[1] = z_gdb_getchar();
110 
111 	if (hex2bin(checksum_buf, 2, &expected_checksum, 1) == 0) {
112 		return -1;
113 	}
114 
115 	/* Verify checksum */
116 	if (checksum != expected_checksum) {
117 		LOG_DBG("Bad checksum. Got 0x%x but was expecting: 0x%x",
118 			checksum, expected_checksum);
119 		/* NACK packet */
120 		z_gdb_putchar('-');
121 		return -1;
122 	}
123 
124 	/* ACK packet */
125 	z_gdb_putchar('+');
126 
127 	return 0;
128 }
129 
130 /**
131  * Read data from a given memory.
132  *
133  * Return 0 in case of success, otherwise -1
134  */
gdb_mem_read(uint8_t * buf,size_t buf_len,uintptr_t addr,size_t len)135 static int gdb_mem_read(uint8_t *buf, size_t buf_len,
136 			uintptr_t addr, size_t len)
137 {
138 	uint8_t data;
139 	size_t pos, count = 0;
140 
141 	if (len > buf_len) {
142 		return -1;
143 	}
144 
145 	/* Read from system memory */
146 	for (pos = 0; pos < len; pos++) {
147 		data = *(uint8_t *)(addr + pos);
148 		count += bin2hex(&data, 1, buf + count, buf_len - count);
149 	}
150 
151 	return count;
152 }
153 
154 /**
155  * Write data in a given memory.
156  *
157  * Return 0 in case of success, otherwise -1
158  */
gdb_mem_write(const uint8_t * buf,uintptr_t addr,size_t len)159 static int gdb_mem_write(const uint8_t *buf, uintptr_t addr,
160 			 size_t len)
161 {
162 	uint8_t data;
163 
164 	while (len > 0) {
165 		size_t ret = hex2bin(buf, 2, &data, sizeof(data));
166 
167 		if (ret == 0) {
168 			return -1;
169 		}
170 
171 		*(uint8_t *)addr = data;
172 
173 		addr++;
174 		buf += 2;
175 		len--;
176 	}
177 
178 	return 0;
179 }
180 
181 /**
182  * Send a exception packet "T <value>"
183  */
gdb_send_exception(uint8_t * buf,size_t len,uint8_t exception)184 static int gdb_send_exception(uint8_t *buf, size_t len, uint8_t exception)
185 {
186 	size_t size;
187 
188 	*buf = 'T';
189 	size = bin2hex(&exception, 1, buf + 1, len - 1);
190 	if (size == 0) {
191 		return -1;
192 	}
193 
194 	/* Related to 'T' */
195 	size++;
196 
197 	return gdb_send_packet(buf, size);
198 }
199 
200 /**
201  * Synchronously communicate with gdb on the host
202  */
z_gdb_main_loop(struct gdb_ctx * ctx,bool start)203 int z_gdb_main_loop(struct gdb_ctx *ctx, bool start)
204 {
205 	uint8_t buf[GDB_PACKET_SIZE];
206 	enum loop_state {
207 		RECEIVING,
208 		CONTINUE,
209 		FAILED
210 	} state;
211 
212 	state = RECEIVING;
213 
214 	if (start == false) {
215 		gdb_send_exception(buf, sizeof(buf), ctx->exception);
216 	}
217 
218 #define CHECK_FAILURE(condition)		\
219 	{					\
220 		if ((condition)) {		\
221 			state = FAILED;	\
222 			break;			\
223 		}				\
224 	}
225 
226 #define CHECK_SYMBOL(c)					\
227 	{							\
228 		CHECK_FAILURE(ptr == NULL || *ptr != (c));	\
229 		ptr++;						\
230 	}
231 
232 #define CHECK_INT(arg)							\
233 	{								\
234 		arg = strtol((const char *)ptr, (char **)&ptr, 16);	\
235 		CHECK_FAILURE(ptr == NULL);				\
236 	}
237 
238 	while (state == RECEIVING) {
239 		uint8_t *ptr;
240 		size_t data_len, pkt_len;
241 		uintptr_t addr;
242 		int ret;
243 
244 		ret = gdb_get_packet(buf, sizeof(buf), &pkt_len);
245 		CHECK_FAILURE(ret == -1);
246 
247 		if (pkt_len == 0) {
248 			continue;
249 		}
250 
251 		ptr = buf;
252 
253 		switch (*ptr++) {
254 
255 		/**
256 		 * Read from the memory
257 		 * Format: m addr,length
258 		 */
259 		case 'm':
260 			CHECK_INT(addr);
261 			CHECK_SYMBOL(',');
262 			CHECK_INT(data_len);
263 
264 			/* Read Memory */
265 
266 			/*
267 			 * GDB ask the guest to read parameters when
268 			 * the user request backtrace. If the
269 			 * parameter is a NULL pointer this will cause
270 			 * a fault. Just send a packet informing that
271 			 * this address is invalid
272 			 */
273 			if (addr == 0L) {
274 				gdb_send_packet(GDB_ERROR_MEMORY, 3);
275 				break;
276 			}
277 			ret = gdb_mem_read(buf, sizeof(buf), addr, data_len);
278 			CHECK_FAILURE(ret == -1);
279 			gdb_send_packet(buf, ret);
280 			break;
281 
282 		/**
283 		 * Write to memory
284 		 * Format: M addr,length:val
285 		 */
286 		case 'M':
287 			CHECK_INT(addr);
288 			CHECK_SYMBOL(',');
289 			CHECK_INT(data_len);
290 			CHECK_SYMBOL(':');
291 
292 			if (addr == 0L) {
293 				gdb_send_packet(GDB_ERROR_MEMORY, 3);
294 				break;
295 			}
296 
297 			/* Write Memory */
298 			pkt_len = gdb_mem_write(ptr, addr, data_len);
299 			CHECK_FAILURE(pkt_len == -1);
300 			gdb_send_packet("OK", 2);
301 			break;
302 
303 		/*
304 		 * Continue ignoring the optional address
305 		 * Format: c addr
306 		 */
307 		case 'c':
308 			arch_gdb_continue();
309 			state = CONTINUE;
310 			break;
311 
312 		/*
313 		 * Step one instruction ignoring the optional address
314 		 * s addr..addr
315 		 */
316 		case 's':
317 			arch_gdb_step();
318 			state = CONTINUE;
319 			break;
320 
321 		/*
322 		 * Read all registers
323 		 * Format: g
324 		 */
325 		case 'g':
326 			pkt_len = bin2hex((const uint8_t *)&(ctx->registers),
327 				  sizeof(ctx->registers), buf, sizeof(buf));
328 			CHECK_FAILURE(pkt_len == 0);
329 			gdb_send_packet(buf, pkt_len);
330 			break;
331 
332 		/**
333 		 * Write the value of the CPU registers
334 		 * Fromat: G XX...
335 		 */
336 		case 'G':
337 			pkt_len = hex2bin(ptr, pkt_len - 1,
338 					 (uint8_t *)&(ctx->registers),
339 					 sizeof(ctx->registers));
340 			CHECK_FAILURE(pkt_len == 0);
341 			gdb_send_packet("OK", 2);
342 			break;
343 
344 		/**
345 		 * Read the value of a register
346 		 * Format: p n
347 		 */
348 		case 'p':
349 			CHECK_INT(addr);
350 			CHECK_FAILURE(addr >= ARCH_GDB_NUM_REGISTERS);
351 
352 			/* Read Register */
353 			pkt_len = bin2hex(
354 				(const uint8_t *)&(ctx->registers[addr]),
355 				sizeof(ctx->registers[addr]),
356 				buf, sizeof(buf));
357 			CHECK_FAILURE(pkt_len == 0);
358 			gdb_send_packet(buf, pkt_len);
359 			break;
360 
361 		/**
362 		 * Write data into a specific register
363 		 * Format: P register=value
364 		 */
365 		case 'P':
366 			CHECK_INT(addr);
367 			CHECK_SYMBOL('=');
368 
369 			/*
370 			 * GDB requires orig_eax that seems to be
371 			 * Linux specific. Unfortunately if we just
372 			 * return "E01" gdb will stop.  So, we just
373 			 * send "OK" and ignore it.
374 			 */
375 			if (addr < ARCH_GDB_NUM_REGISTERS) {
376 				pkt_len = hex2bin(ptr, strlen(ptr),
377 					  (uint8_t *)&(ctx->registers[addr]),
378 					  sizeof(ctx->registers[addr]));
379 				CHECK_FAILURE(pkt_len == 0);
380 			}
381 			gdb_send_packet("OK", 2);
382 			break;
383 
384 
385 		/* What cause the pause  */
386 		case '?':
387 			gdb_send_exception(buf, sizeof(buf),
388 					   ctx->exception);
389 			break;
390 
391 		/*
392 		 * Not supported action
393 		 */
394 		default:
395 			gdb_send_packet(NULL, 0);
396 			break;
397 		}
398 	}
399 
400 	if (state == FAILED) {
401 		gdb_send_packet(GDB_ERROR_GENERAL, 3);
402 		return -1;
403 	}
404 
405 #undef CHECK_FAILURE
406 #undef CHECK_INT
407 #undef CHECK_SYMBOL
408 
409 	return 0;
410 }
411 
gdb_init(const struct device * arg)412 int gdb_init(const struct device *arg)
413 {
414 	ARG_UNUSED(arg);
415 
416 	if (z_gdb_backend_init() == -1) {
417 		LOG_ERR("Could not initialize gdbstub backend.");
418 		return -1;
419 	}
420 
421 	arch_gdb_init();
422 	return 0;
423 }
424 
425 SYS_INIT(gdb_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
426