xref: /original-bsd/sys/i386/i386/kgdb_stub.c (revision b9df2d9d)
1 /*
2  * Copyright (c) 1990 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)kgdb_stub.c	7.3 (Berkeley) 11/13/91
8  */
9 /*
10  * "Stub" to allow remote cpu to debug over a serial line using gdb.
11  */
12 #ifdef KGDB
13 #ifndef lint
14 static char rcsid[] = "$Header: /u/donn/c/gdb/kernel/RCS/kgdb_stub.c,v 1.2 91/03/31 19:22:46 donn Exp Locker: donn $";
15 #endif
16 
17 #include "param.h"
18 #include "systm.h"
19 #include "../include/trap.h"
20 #include "../include/cpu.h"
21 #include "../include/psl.h"
22 #include "../include/reg.h"
23 #include "buf.h"
24 #include "cons.h"
25 #include "errno.h"
26 
27 #include "kgdb_proto.h"
28 #include "machine/remote-sl.h"
29 
30 extern int kernacc();
31 #if 0
32 extern void chgkprot();
33 #endif
34 
35 #ifndef KGDBDEV
36 #define KGDBDEV -1
37 #endif
38 #ifndef KGDBRATE
39 #define KGDBRATE 9600
40 #endif
41 
42 int kgdb_dev = KGDBDEV;		/* remote debugging device (-1 if none) */
43 int kgdb_rate = KGDBRATE;	/* remote debugging baud rate */
44 int kgdb_active = 0;            /* remote debugging active if != 0 */
45 int kgdb_debug_init = 0;	/* != 0 waits for remote at system init */
46 int kgdb_debug_panic = 1;	/* != 0 waits for remote on panic */
47 int kgdb_debug = 3;
48 
49 #define GETC	((*kgdb_getc)(kgdb_dev))
50 #define PUTC(c)	((*kgdb_putc)(kgdb_dev, c))
51 #define PUTESC(c) { \
52 	if (c == FRAME_END) { \
53 		PUTC(FRAME_ESCAPE); \
54 		c = TRANS_FRAME_END; \
55 	} else if (c == FRAME_ESCAPE) { \
56 		PUTC(FRAME_ESCAPE); \
57 		c = TRANS_FRAME_ESCAPE; \
58 	} \
59 	PUTC(c); \
60 }
61 
62 static int (*kgdb_getc)();
63 static int (*kgdb_putc)();
64 
65 /*
66  * Send a message.  The host gets one chance to read it.
67  */
68 static void
69 kgdb_send(type, bp, len)
70 	register u_char type;
71 	register u_char *bp;
72 	register int len;
73 {
74 	register u_char csum;
75 	register u_char *ep = bp + len;
76 
77 	csum = type;
78 	PUTESC(type)
79 
80 	while (bp < ep) {
81 		type = *bp++;
82 		csum += type;
83 		PUTESC(type)
84 	}
85 	csum = -csum;
86 	PUTESC(csum)
87 	PUTC(FRAME_END);
88 }
89 
90 static int
91 kgdb_recv(bp, lenp)
92 	u_char *bp;
93 	int *lenp;
94 {
95 	register u_char c, csum;
96 	register int escape, len;
97 	register int type;
98 
99 	csum = len = escape = 0;
100 	type = -1;
101 	while (1) {
102 		c = GETC;
103 		switch (c) {
104 
105 		case FRAME_ESCAPE:
106 			escape = 1;
107 			continue;
108 
109 		case TRANS_FRAME_ESCAPE:
110 			if (escape)
111 				c = FRAME_ESCAPE;
112 			break;
113 
114 		case TRANS_FRAME_END:
115 			if (escape)
116 				c = FRAME_END;
117 			break;
118 
119 		case FRAME_END:
120 			if (type < 0 || --len < 0) {
121 				csum = len = escape = 0;
122 				type = -1;
123 				continue;
124 			}
125 			if (csum != 0) {
126 				return (0);
127 			}
128 			*lenp = len;
129 			return type;
130 		}
131 		csum += c;
132 		if (type < 0) {
133 			type = c;
134 			escape = 0;
135 			continue;
136 		}
137 		if (++len > SL_BUFSIZE) {
138 			while (GETC != FRAME_END)
139 				;
140 			return (0);
141 		}
142 		*bp++ = c;
143 		escape = 0;
144 	}
145 }
146 
147 /*
148  * Translate a trap number into a unix compatible signal value.
149  * (gdb only understands unix signal numbers).
150  */
151 static int
152 computeSignal(type)
153 	int type;
154 {
155 	int sigval;
156 
157 	switch (type) {
158 	case T_RESADFLT:
159 	case T_PRIVINFLT:
160 	case T_RESOPFLT:
161 	case T_ALIGNFLT:
162 	case T_FPOPFLT:
163 		sigval = SIGILL;
164 		break;
165 	case T_BPTFLT:
166 	case T_TRCTRAP:
167 	case T_KDBTRAP:
168 		sigval = SIGTRAP;
169 		break;
170 	case T_ARITHTRAP:
171 	case T_DIVIDE:
172 	case T_OFLOW:
173 	case T_BOUND:
174 	case T_DNA:
175 		sigval = SIGFPE;
176 		break;
177 	case T_SEGFLT:
178 	case T_PROTFLT:
179 	case T_SEGNPFLT:
180 	case T_BUSERR:
181 		sigval = SIGBUS;
182 		break;
183 	case T_PAGEFLT:
184 	case T_TABLEFLT:
185 		sigval = SIGSEGV;
186 		break;
187 
188 	case T_SYSCALL:		/* ??? */
189 	case T_ASTFLT:		/* ??? */
190 	case T_KSPNOTVAL:	/* ??? */
191 	case T_NMI:		/* ??? */
192 	case T_DOUBLEFLT:	/* ??? */
193 	case T_TSSFLT:		/* ??? */
194 	case T_STKFLT:		/* ??? */
195 	case T_RESERVED:	/* ??? */
196 	default:
197 		sigval = SIGEMT;
198 		break;
199 	}
200 	return (sigval);
201 }
202 
203 /*
204  * Trap into kgdb to wait for debugger to connect,
205  * noting on the console why nothing else is going on.
206  */
207 kgdb_connect(verbose)
208 	int verbose;
209 {
210 
211 	if (verbose)
212 		printf("kgdb waiting...");
213 #ifdef DONN
214 	if (kgdb_debug > 3)
215 		pg("kgdb_connect: trapping\n");
216 #endif
217 	/* trap into kgdb */
218 	asm volatile ("int3");
219 	if (verbose)
220 		printf("connected.\n");
221 }
222 
223 /*
224  * Decide what to do on panic.
225  */
226 kgdb_panic()
227 {
228 
229 	if (kgdb_active == 0 && kgdb_debug_panic)
230 		kgdb_connect(1);
231 }
232 
233 /*
234  * Definitions exported from gdb.
235  */
236 #define NUM_REGS 16
237 #define REGISTER_BYTES (NUM_REGS * 4)
238 #define REGISTER_BYTE(N)  ((N)*4)
239 
240 #define GDB_SR 8
241 #define GDB_PC 9
242 
243 static inline void
244 kgdb_copy(register u_char *src, register u_char *dst, register u_int nbytes)
245 {
246 	register u_char *ep = src + nbytes;
247 
248 	while (src < ep)
249 		*dst++ = *src++;
250 }
251 
252 #ifndef tISP
253 #define	tISP	(5)	/* XXX */
254 #endif
255 
256 static const char trapmap[] = 		/* from gdb */
257 {
258 	tEAX, tECX, tEDX, tEBX,
259 	tISP, tEBP, tESI, tEDI,
260 	tEIP, tEFLAGS, tCS, tDS,	/* tSS doesn't exist for kernel trap */
261 	tDS, tES, tES, tES		/* lies: no fs or gs */
262 };
263 
264 static inline void
265 regs_to_gdb(struct trapframe *fp, register u_long *gdb)
266 {
267 	register const char *tp;
268 	register u_long *regs = (u_long *)fp;
269 
270 	for (tp = trapmap; tp < &trapmap[sizeof trapmap]; ++tp)
271 		*gdb++ = regs[*tp];
272 }
273 
274 static inline void
275 gdb_to_regs(struct trapframe *fp, register u_long *gdb)
276 {
277 	register const char *tp;
278 	register u_long *regs = (u_long *)fp;
279 
280 	for (tp = trapmap; tp < &trapmap[sizeof trapmap]; ++tp)
281 		regs[*tp] = *gdb++;
282 }
283 
284 static u_long reg_cache[NUM_REGS];
285 static u_char inbuffer[SL_BUFSIZE];
286 static u_char outbuffer[SL_BUFSIZE];
287 
288 /*
289  * This function does all command procesing for interfacing to
290  * a remote gdb.
291  */
292 int
293 kgdb_trap(int type, struct trapframe *frame)
294 {
295 	register u_long len;
296 	u_char *addr;
297 	register u_char *cp;
298 	register u_char out, in;
299 	register int outlen;
300 	int inlen;
301 	u_long gdb_regs[NUM_REGS];
302 	int saved_kgdb_active = kgdb_active;
303 
304 	if (kgdb_dev < 0) {
305 		/* not debugging */
306 		return (0);
307 	}
308 	if (kgdb_active == 0) {
309 #ifdef DONN
310 		if (kgdb_debug > 3)
311 			pg("kgdb_trap: start initialization\n");
312 #endif
313 		if (type != T_BPTFLT) {
314 			/* No debugger active -- let trap handle this. */
315 			return (0);
316 		}
317 		kgdb_getc = 0;
318 		for (inlen = 0; constab[inlen].cn_probe; inlen++)
319 		    if (major(constab[inlen].cn_dev) == major(kgdb_dev)) {
320 			kgdb_getc = constab[inlen].cn_getc;
321 			kgdb_putc = constab[inlen].cn_putc;
322 			break;
323 		}
324 #ifdef DONN
325 		if (kgdb_debug > 3)
326 			pg("kgdb_trap: kgdb_getc = %x, kgdb_putc = %x\n",
327 				kgdb_getc, kgdb_putc);
328 #endif
329 		if (kgdb_getc == 0 || kgdb_putc == 0)
330 			return (0);
331 		/*
332 		 * If the packet that woke us up isn't an exec packet,
333 		 * ignore it since there is no active debugger.  Also,
334 		 * we check that it's not an ack to be sure that the
335 		 * remote side doesn't send back a response after the
336 		 * local gdb has exited.  Otherwise, the local host
337 		 * could trap into gdb if it's running a gdb kernel too.
338 		 */
339 		in = GETC;
340 #ifdef DONN
341 		if (kgdb_debug > 3)
342 			pg("kgdb_trap: looking for sync %x\n", in);
343 #endif
344 		/*
345 		 * If we came in asynchronously through the serial line,
346 		 * the framing character is eaten by the receive interrupt,
347 		 * but if we come in through a synchronous trap (i.e., via
348 		 * kgdb_connect()), we will see the extra character.
349 		 */
350 		if (in == FRAME_END)
351 			in = GETC;
352 
353 		if (KGDB_CMD(in) != KGDB_EXEC || (in & KGDB_ACK) != 0)
354 			return (0);
355 		while (GETC != FRAME_END)
356 			;
357 		/*
358 		 * Do the printf *before* we ack the message.  This way
359 		 * we won't drop any inbound characters while we're
360 		 * doing the polling printf.
361 		 */
362 		printf("kgdb started from device %x\n", kgdb_dev);
363 		kgdb_send(in | KGDB_ACK, (u_char *)0, 0);
364 		kgdb_active = 1;
365 	}
366 	/*
367 	 * Stick frame regs into our reg cache then tell remote host
368 	 * that an exception has occured.
369 	 */
370 	regs_to_gdb(frame, gdb_regs);
371 	if (saved_kgdb_active == kgdb_active) {
372 		/*
373 		 * Don't send an asynchronous SIGNAL message when we hit
374 		 * the first breakpoint.  Otherwise, we will drop the incoming
375 		 * packet while we output this one (and on entry the other
376 		 * side isn't interested in the SIGNAL type -- if it is,
377 		 * it will have used a signal packet.)
378 		 */
379 		outbuffer[0] = computeSignal(type);
380 		kgdb_send(KGDB_SIGNAL, outbuffer, 1);
381 	}
382 
383 	while (1) {
384 		in = kgdb_recv(inbuffer, &inlen);
385 		if (in == 0 || (in & KGDB_ACK))
386 			/* Ignore inbound acks and error conditions. */
387 			continue;
388 
389 		out = in | KGDB_ACK;
390 		switch (KGDB_CMD(in)) {
391 
392 		case KGDB_SIGNAL:
393 			/*
394 			 * if this command came from a running gdb,
395 			 * answer it -- the other guy has no way of
396 			 * knowing if we're in or out of this loop
397 			 * when he issues a "remote-signal".  (Note
398 			 * that without the length check, we could
399 			 * loop here forever if the ourput line is
400 			 * looped back or the remote host is echoing.)
401 			 */
402 			if (inlen == 0) {
403 				outbuffer[0] = computeSignal(type);
404 				kgdb_send(KGDB_SIGNAL, outbuffer, 1);
405 			}
406 			continue;
407 
408 		case KGDB_REG_R:
409 		case KGDB_REG_R | KGDB_DELTA:
410 			cp = outbuffer;
411 			outlen = 0;
412 			for (len = inbuffer[0]; len < NUM_REGS; ++len) {
413 				if (reg_cache[len] != gdb_regs[len] ||
414 				    (in & KGDB_DELTA) == 0) {
415 					if (outlen + 5 > SL_MAXMSG) {
416 						out |= KGDB_MORE;
417 						break;
418 					}
419 					cp[outlen] = len;
420 					kgdb_copy((u_char *)&gdb_regs[len],
421 						  &cp[outlen + 1], 4);
422 					reg_cache[len] = gdb_regs[len];
423 					outlen += 5;
424 				}
425 			}
426 			break;
427 
428 		case KGDB_REG_W:
429 		case KGDB_REG_W | KGDB_DELTA:
430 			cp = inbuffer;
431 			for (len = 0; len < inlen; len += 5) {
432 				register int j = cp[len];
433 
434 				kgdb_copy(&cp[len + 1],
435 					  (u_char *)&gdb_regs[j], 4);
436 				reg_cache[j] = gdb_regs[j];
437 			}
438 			gdb_to_regs(frame, gdb_regs);
439 			outlen = 0;
440 			break;
441 
442 		case KGDB_MEM_R:
443 			len = inbuffer[0];
444 			kgdb_copy(&inbuffer[1], (u_char *)&addr, 4);
445 			if (len + 1 > SL_MAXMSG) {
446 				outlen = 1;
447 				outbuffer[0] = E2BIG;
448 			} else if (!kgdb_acc(addr, len, B_READ)) {
449 				outlen = 1;
450 				outbuffer[0] = EFAULT;
451 			} else {
452 				outlen = len + 1;
453 				outbuffer[0] = 0;
454 				kgdb_copy(addr, &outbuffer[1], len);
455 			}
456 			break;
457 
458 		case KGDB_MEM_W:
459 			len = inlen - 4;
460 			kgdb_copy(inbuffer, (u_char *)&addr, 4);
461 			outlen = 1;
462 			if (!kgdb_acc(addr, len, B_READ))
463 				outbuffer[0] = EFAULT;
464 			else {
465 				outbuffer[0] = 0;
466 #if 0				/* 386 can't write-protect against kernel! */
467 				if (!kgdb_acc(addr, len, B_WRITE))
468 					chgkprot(addr, len, B_WRITE);
469 #endif
470 				kgdb_copy(&inbuffer[4], addr, len);
471 			}
472 			break;
473 
474 		case KGDB_KILL:
475 			kgdb_active = 0;
476 			printf("kgdb detached\n");
477 			/* fall through */
478 		case KGDB_CONT:
479 			kgdb_send(out, 0, 0);
480 			frame->tf_eflags &=~ PSL_T;
481 			return (1);
482 
483 		case KGDB_STEP:
484 			kgdb_send(out, 0, 0);
485 			frame->tf_eflags |= PSL_T;
486 			return (1);
487 
488 		case KGDB_EXEC:
489 		default:
490 			/* Unknown command.  Ack with a null message. */
491 			outlen = 0;
492 			break;
493 		}
494 		/* Send the reply */
495 		kgdb_send(out, outbuffer, outlen);
496 	}
497 }
498 
499 /*
500  * XXX do kernacc call if safe, otherwise attempt
501  * to simulate by simple bounds-checking.
502  */
503 kgdb_acc(addr, len, rw)
504 	caddr_t addr;
505 {
506 	extern char proc0paddr[], kstack[];		/* XXX! */
507 	extern char *kernel_map;		/* XXX! */
508 
509 	if (kstack <= addr && addr < kstack + UPAGES * NBPG)
510 		/*
511 		 * Horrid hack -- the kernel stack is mapped
512 		 * by the user page table, but we guarantee (?) their presence.
513 		 */
514 		return (1);
515 	if (kernel_map != NULL)
516 		return (kernacc(addr, len, rw));
517 #if 0
518 	if (addr < proc0paddr + UPAGES * NBPG  ||
519 	    kstack <= addr && addr < kstack + UPAGES * NBPG)
520 		return (1);
521 #endif
522 	return (0);
523 }
524 #endif
525