This source file includes following definitions.
- kgdb_copy
- kgdb_zero
- digit2i
- i2digit
- mem2hex
- hex2mem
- hex2i
- kgdb_send
- kgdb_recv
- kgdb_attach
- kgdb_trap
- kgdb_connect
- kgdb_panic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/kgdb.h>
51
52
53
54
55 #ifndef KGDBDEV
56 #define KGDBDEV -1
57 #endif
58 #ifndef KGDBRATE
59 #define KGDBRATE 19200
60 #endif
61
62 int kgdb_dev = KGDBDEV;
63 int kgdb_rate = KGDBRATE;
64 int kgdb_active = 0;
65 int kgdb_debug_init = 0;
66 int kgdb_debug_panic = 0;
67 label_t *kgdb_recover = 0;
68
69 static void kgdb_copy(void *, void *, int);
70
71 static void kgdb_send(u_char *);
72 static int kgdb_recv(u_char *, int);
73 static int digit2i(u_char);
74 static u_char i2digit(int);
75 static void mem2hex(void *, void *, int);
76 static u_char *hex2mem(void *, u_char *, int);
77 static vaddr_t hex2i(u_char **);
78
79 static int (*kgdb_getc)(void *);
80 static void (*kgdb_putc)(void *, int);
81 static void *kgdb_ioarg;
82
83 static u_char buffer[KGDB_BUFLEN];
84 static kgdb_reg_t gdb_regs[KGDB_NUMREGS];
85
86 #define GETC() ((*kgdb_getc)(kgdb_ioarg))
87 #define PUTC(c) ((*kgdb_putc)(kgdb_ioarg, c))
88
89
90
91
92 static void
93 kgdb_copy(void *vsrc, void *vdst, int len)
94 {
95 char *src = vsrc;
96 char *dst = vdst;
97
98 while (--len >= 0)
99 *dst++ = *src++;
100 }
101
102 #if 0
103
104 static void
105 kgdb_zero(void *vptr, int len)
106 {
107 char *ptr = vptr;
108
109 while (--len >= 0)
110 *ptr++ = (char) 0;
111 }
112 #endif
113
114
115
116
117
118
119 static int
120 digit2i(u_char c)
121 {
122 if (c >= '0' && c <= '9')
123 return (c - '0');
124 else if (c >= 'a' && c <= 'f')
125 return (c - 'a' + 10);
126 else if (c >= 'A' && c <= 'F')
127
128 return (c - 'A' + 10);
129 else
130 return (-1);
131 }
132
133
134
135
136
137 static u_char
138 i2digit(int n)
139 {
140 return ("0123456789abcdef"[n & 0x0f]);
141 }
142
143
144
145
146 static void
147 mem2hex(void *vdst, void *vsrc, int len)
148 {
149 u_char *dst = vdst;
150 u_char *src = vsrc;
151
152 while (len--) {
153 *dst++ = i2digit(*src >> 4);
154 *dst++ = i2digit(*src++);
155 }
156 *dst = '\0';
157 }
158
159
160
161
162
163
164
165 static u_char *
166 hex2mem(void *vdst, u_char *src, int maxlen)
167 {
168 u_char *dst = vdst;
169 int msb, lsb;
170
171 while (*src && maxlen--) {
172 msb = digit2i(*src++);
173 if (msb < 0)
174 return (src - 1);
175 lsb = digit2i(*src++);
176 if (lsb < 0)
177 return (NULL);
178 *dst++ = (msb << 4) | lsb;
179 }
180 return (src);
181 }
182
183
184
185
186
187
188 static vaddr_t
189 hex2i(u_char **srcp)
190 {
191 char *src = *srcp;
192 vaddr_t r = 0;
193 int nibble;
194
195 while ((nibble = digit2i(*src)) >= 0) {
196 r *= 16;
197 r += nibble;
198 src++;
199 }
200 *srcp = src;
201 return (r);
202 }
203
204
205
206
207 static void
208 kgdb_send(u_char *bp)
209 {
210 u_char *p;
211 u_char csum, c;
212
213 #ifdef DEBUG_KGDB
214 printf("kgdb_send: %s\n", bp);
215 #endif
216 do {
217 p = bp;
218 PUTC(KGDB_START);
219 for (csum = 0; (c = *p); p++) {
220 PUTC(c);
221 csum += c;
222 }
223 PUTC(KGDB_END);
224 PUTC(i2digit(csum >> 4));
225 PUTC(i2digit(csum));
226 } while ((c = GETC() & 0x7f) == KGDB_BADP);
227 }
228
229
230
231
232 static int
233 kgdb_recv(u_char *bp, int maxlen)
234 {
235 u_char *p;
236 int c, csum;
237 int len;
238
239 do {
240 p = bp;
241 csum = len = 0;
242 while ((c = GETC()) != KGDB_START)
243 ;
244
245 while ((c = GETC()) != KGDB_END && len < maxlen) {
246 c &= 0x7f;
247 csum += c;
248 *p++ = c;
249 len++;
250 }
251 csum &= 0xff;
252 *p = '\0';
253
254 if (len >= maxlen) {
255 PUTC(KGDB_BADP);
256 continue;
257 }
258
259 csum -= digit2i(GETC()) * 16;
260 csum -= digit2i(GETC());
261
262 if (csum == 0) {
263 PUTC(KGDB_GOODP);
264
265 if (bp[2] == ':') {
266 PUTC(bp[0]);
267 PUTC(bp[1]);
268 len -= 3;
269 kgdb_copy(bp + 3, bp, len);
270 }
271 break;
272 }
273 PUTC(KGDB_BADP);
274 } while (1);
275 #ifdef DEBUG_KGDB
276 printf("kgdb_recv: %s\n", bp);
277 #endif
278 return (len);
279 }
280
281
282
283
284 void
285 kgdb_attach(int (*getfn)(void *), void (*putfn)(void *, int), void *ioarg)
286 {
287 kgdb_getc = getfn;
288 kgdb_putc = putfn;
289 kgdb_ioarg = ioarg;
290 }
291
292
293
294
295
296
297
298
299 int
300 kgdb_trap(int type, db_regs_t *regs)
301 {
302 label_t jmpbuf;
303 vaddr_t addr;
304 size_t len;
305 u_char *p;
306
307 if (kgdb_dev < 0 || kgdb_getc == NULL) {
308
309 return (0);
310 }
311
312
313 if (kgdb_recover != 0) {
314 printf("kgdb: caught trap 0x%x at %p\n",
315 type, (void *)PC_REGS(regs));
316 kgdb_send("E0E");
317 longjmp(kgdb_recover);
318 }
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340 if (kgdb_active == 0) {
341 if (!IS_BREAKPOINT_TRAP(type, 0)) {
342
343 return (0);
344 }
345
346 #ifdef FIXUP_PC_AFTER_BREAK
347 FIXUP_PC_AFTER_BREAK(regs);
348 #endif
349
350 #ifdef PC_ADVANCE
351 PC_ADVANCE(regs);
352 #else
353 PC_REGS(regs) += BKPT_SIZE;
354 #endif
355 kgdb_active = 1;
356 } else {
357
358 snprintf(buffer, sizeof buffer, "S%02x", kgdb_signal(type));
359 kgdb_send(buffer);
360 }
361
362
363 kgdb_getregs(regs, gdb_regs);
364
365
366
367
368
369 (void)setjmp((kgdb_recover = &jmpbuf));
370 for (;;) {
371 kgdb_recv(buffer, sizeof(buffer));
372 switch (buffer[0]) {
373
374 default:
375
376 kgdb_send("");
377 continue;
378
379 case KGDB_SIGNAL:
380
381
382
383
384
385
386 snprintf(buffer, sizeof buffer, "S%02x",
387 kgdb_signal(type));
388 kgdb_send(buffer);
389 continue;
390
391 case KGDB_REG_R:
392 mem2hex(buffer, gdb_regs, sizeof(gdb_regs));
393 kgdb_send(buffer);
394 continue;
395
396 case KGDB_REG_W:
397 p = hex2mem(gdb_regs, buffer + 1, sizeof(gdb_regs));
398 if (p == NULL || *p != '\0')
399 kgdb_send("E01");
400 else {
401 kgdb_setregs(regs, gdb_regs);
402 kgdb_send("OK");
403 }
404 continue;
405
406 case KGDB_MEM_R:
407 p = buffer + 1;
408 addr = hex2i(&p);
409 if (*p++ != ',') {
410 kgdb_send("E02");
411 continue;
412 }
413 len = hex2i(&p);
414 if (*p != '\0') {
415 kgdb_send("E03");
416 continue;
417 }
418 if (len > sizeof(buffer) / 2) {
419 kgdb_send("E04");
420 continue;
421 }
422 if (kgdb_acc(addr, len) == 0) {
423 kgdb_send("E05");
424 continue;
425 }
426 db_read_bytes(addr, (size_t)len,
427 (char *)buffer + sizeof(buffer) / 2);
428 mem2hex(buffer, buffer + sizeof(buffer) / 2, len);
429 kgdb_send(buffer);
430 continue;
431
432 case KGDB_MEM_W:
433 p = buffer + 1;
434 addr = hex2i(&p);
435 if (*p++ != ',') {
436 kgdb_send("E06");
437 continue;
438 }
439 len = hex2i(&p);
440 if (*p++ != ':') {
441 kgdb_send("E07");
442 continue;
443 }
444 if (len > (sizeof(buffer) - (p - buffer))) {
445 kgdb_send("E08");
446 continue;
447 }
448 p = hex2mem(buffer, p, sizeof(buffer));
449 if (p == NULL) {
450 kgdb_send("E09");
451 continue;
452 }
453 if (kgdb_acc(addr, len) == 0) {
454 kgdb_send("E0A");
455 continue;
456 }
457 db_write_bytes(addr, (size_t)len, (char *)buffer);
458 kgdb_send("OK");
459 continue;
460
461 case KGDB_DETACH:
462 kgdb_active = 0;
463 printf("kgdb detached\n");
464 db_clear_single_step(regs);
465 kgdb_send("OK");
466 goto out;
467
468 case KGDB_KILL:
469 kgdb_active = 0;
470 printf("kgdb detached\n");
471 db_clear_single_step(regs);
472 goto out;
473
474 case KGDB_CONT:
475 if (buffer[1]) {
476 p = buffer + 1;
477 addr = hex2i(&p);
478 if (*p) {
479 kgdb_send("E0B");
480 continue;
481 }
482 PC_REGS(regs) = addr;
483 }
484 db_clear_single_step(regs);
485 goto out;
486
487 case KGDB_STEP:
488 if (buffer[1]) {
489 p = buffer + 1;
490 addr = hex2i(&p);
491 if (*p) {
492 kgdb_send("E0B");
493 continue;
494 }
495 PC_REGS(regs) = addr;
496 }
497 db_set_single_step(regs);
498 goto out;
499 }
500 }
501 out:
502 kgdb_recover = 0;
503 return (1);
504 }
505
506
507
508
509
510 void
511 kgdb_connect(int verbose)
512 {
513 if (kgdb_dev < 0)
514 return;
515
516 KGDB_PREPARE;
517
518 if (verbose)
519 printf("kgdb waiting...");
520
521 KGDB_ENTER;
522
523 if (verbose)
524 printf("connected.\n");
525
526 kgdb_debug_panic = 1;
527 }
528
529
530
531
532
533 void
534 kgdb_panic()
535 {
536 if (kgdb_dev >= 0 && kgdb_debug_panic) {
537 printf("entering kgdb\n");
538 kgdb_connect(kgdb_active == 0);
539 }
540 }