|
|
1.1 root 1: /*
2: * Copyright (c) 1988 University of Utah.
3: * Copyright (c) 1990 The Regents of the University of California.
4: * All rights reserved.
5: *
6: * This code is derived from software contributed to Berkeley by
7: * the Systems Programming Group of the University of Utah Computer
8: * Science Department.
9: *
10: * Redistribution is only permitted until one year after the first shipment
11: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
12: * binary forms are permitted provided that: (1) source distributions retain
13: * this entire copyright notice and comment, and (2) distributions including
14: * binaries display the following acknowledgement: This product includes
15: * software developed by the University of California, Berkeley and its
16: * contributors'' in the documentation or other materials provided with the
17: * distribution and in all advertising materials mentioning features or use
18: * of this software. Neither the name of the University nor the names of
19: * its contributors may be used to endorse or promote products derived from
20: * this software without specific prior written permission.
21: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
22: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
23: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24: *
25: * @(#)kgdb_stub.c 7.3 (Berkeley) 6/22/90
26: */
27:
28: /*
29: *
30: * The following gdb commands are supported:
31: *
32: * command function Return value
33: *
34: * g return the value of the CPU registers hex data or ENN
35: * G set the value of the CPU registers OK or ENN
36: *
37: * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
38: * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
39: *
40: * c Resume at current address SNN ( signal NN)
41: * cAA..AA Continue at address AA..AA SNN
42: *
43: * s Step one instruction SNN
44: * sAA..AA Step one instruction from AA..AA SNN
45: *
46: * k kill
47: *
48: * ? What was the last sigval ? SNN (signal NN)
49: *
50: * All commands and responses are sent with a packet which includes a
51: * checksum. A packet consists of
52: *
53: * $<packet info>#<checksum>.
54: *
55: * where
56: * <packet info> :: <characters representing the command or response>
57: * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
58: *
59: * When a packet is received, it is first acknowledged with either '+' or '-'.
60: * '+' indicates a successful transfer. '-' indicates a failed transfer.
61: *
62: * Example:
63: *
64: * Host: Reply:
65: * $m0,10#2a +$00010203040506070809101112131415#42
66: *
67: ****************************************************************************/
68:
69: #ifdef KGDB
70: #include "param.h"
71: #include "systm.h"
72: #include "trap.h"
73: #include "cpu.h"
74: #include "psl.h"
75: #include "reg.h"
76: #include "frame.h"
77: #include "buf.h"
78:
79: extern void printf();
80: extern void bcopy();
81: extern int kernacc();
82: extern void chgkprot();
83:
84: /* # of additional (beyond 4) bytes in 680x0 exception frame format n */
85: static int frame_bytes[16] = {
86: 4, 4, 8, 4,
87: 4, 4, 4, 4,
88: 54, 16, 28, 88,
89: 4, 4, 4, 4
90: };
91:
92: #define USER 040 /* (XXX from trap.c) user-mode flag in type */
93:
94: /*
95: * BUFMAX defines the maximum number of characters in inbound/outbound
96: * buffers. At least NUMREGBYTES*2 are needed for register packets.
97: */
98: #define BUFMAX 512
99:
100: #ifndef KGDBDEV
101: #define KGDBDEV -1
102: #endif
103: #ifndef KGDBRATE
104: #define KGDBRATE 9600
105: #endif
106:
107: int kgdb_dev = KGDBDEV; /* remote debugging device (-1 if none) */
108: int kgdb_rate = KGDBRATE; /* remote debugging baud rate */
109: int kgdb_debug_init = 0; /* != 0 waits for remote at system init */
110: int kgdb_debug = 0; /* > 0 prints command & checksum errors */
111:
112: #include "../hp300/cons.h"
113:
114: #define GETC \
115: (constab[major(kgdb_dev)].cn_getc ? \
116: (*constab[major(kgdb_dev)].cn_getc)(kgdb_dev) : 0)
117: #define PUTC(c) { \
118: if (constab[major(kgdb_dev)].cn_putc) \
119: (*constab[major(kgdb_dev)].cn_putc)(kgdb_dev, c); \
120: }
121:
122: static char hexchars[] = "0123456789abcdef";
123:
124: /*
125: * There are 180 bytes of registers on a 68020 w/68881. Many of the fpa
126: * registers are 12 byte (96 bit) registers.
127: */
128: #define NUMREGBYTES 180
129:
130: static char inbuffer[BUFMAX];
131: static char outbuffer[BUFMAX];
132:
133: static inline int
134: hex(ch)
135: char ch;
136: {
137: if ((ch >= '0') && (ch <= '9'))
138: return (ch - '0');
139: if ((ch >= 'a') && (ch <= 'f'))
140: return (ch - ('a' - 10));
141: return (0);
142: }
143:
144: /* scan for the sequence $<data>#<checksum> */
145: static void
146: getpacket(char *buffer)
147: {
148: unsigned char checksum;
149: unsigned char xmitcsum;
150: int i;
151: int count;
152: char ch;
153:
154: do {
155: /*
156: * wait around for the start character, ignore all other
157: * characters
158: */
159: while ((ch = GETC) != '$')
160: ;
161: checksum = 0;
162: count = 0;
163: xmitcsum = 1;
164:
165: /* now, read until a # or end of buffer is found */
166: while (count < BUFMAX) {
167: ch = GETC;
168: if (ch == '#')
169: break;
170: checksum = checksum + ch;
171: buffer[count] = ch;
172: count = count + 1;
173: }
174: buffer[count] = 0;
175:
176: if (ch == '#') {
177: xmitcsum = hex(GETC) << 4;
178: xmitcsum += hex(GETC);
179: if (kgdb_debug && (checksum != xmitcsum)) {
180: printf(
181: "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
182: checksum, xmitcsum, buffer);
183: }
184: if (checksum != xmitcsum) {
185: PUTC('-'); /* failed checksum */
186: } else {
187: PUTC('+'); /* successful transfer */
188: /*
189: * if a sequence char is present, reply the
190: * sequence ID
191: */
192: if (buffer[2] == ':') {
193: PUTC(buffer[0]);
194: PUTC(buffer[1]);
195: /* remove sequence chars from buffer */
196: for (i = 3; i <= count; ++i)
197: buffer[i - 3] = buffer[i];
198: }
199: }
200: }
201: } while (checksum != xmitcsum);
202: }
203:
204: /*
205: * send the packet in buffer. The host gets one chance to read it. This
206: * routine does not wait for a positive acknowledge.
207: */
208: static void
209: putpacket(char *buffer)
210: {
211: unsigned char checksum;
212: int count;
213: char ch;
214:
215: /* $<packet info>#<checksum>. */
216: do {
217: PUTC('$');
218: checksum = 0;
219: count = 0;
220:
221: while (ch = buffer[count]) {
222: PUTC(ch);
223: checksum += ch;
224: count += 1;
225: }
226: PUTC('#');
227: PUTC(hexchars[checksum >> 4]);
228: PUTC(hexchars[checksum & 15]);
229:
230: } while (0); /* (GETC != '+'); */
231:
232: }
233:
234: static inline void
235: debug_error(char *format, char *parm)
236: {
237: if (kgdb_debug)
238: printf(format, parm);
239: }
240:
241: /*
242: * Convert at most 'dig' digits of hex data in buf into a value.
243: * Stop on non-hex char. Return a pointer to next char in buf.
244: */
245: static char *
246: hex2val(char *buf, int *val, int dig)
247: {
248: int i, v;
249: char ch;
250:
251: v = 0;
252: for (i = dig; --i >= 0; ) {
253: ch = *buf++;
254: if ((ch >= '0') && (ch <= '9'))
255: v = (v << 4) | (ch - '0');
256: else if ((ch >= 'a') && (ch <= 'f'))
257: v = (v << 4) | (ch - ('a' - 10));
258: else {
259: --buf;
260: break;
261: }
262: }
263: *val = v;
264: return (buf);
265: }
266:
267: /*
268: * convert the integer value 'val' into 'dig' hex digits, placing
269: * result in buf. Return a pointer to the last char put in buf (null).
270: */
271: static char *
272: val2hex(char *buf, int val, int dig)
273: {
274: for (dig <<= 2; (dig -= 4) >= 0; )
275: *buf++ = hexchars[(val >> dig) & 0xf];
276: *buf = 0;
277: return (buf);
278: }
279:
280: /*
281: * convert the memory pointed to by mem into hex, placing result in buf.
282: * return a pointer to the last char put in buf (null).
283: */
284: static char *
285: mem2hex(char *buf, char *mem, int count)
286: {
287: if ((count & 1) || ((int)mem & 1)) {
288: char ch;
289:
290: while(--count >= 0) {
291: ch = *mem++;
292: *buf++ = hexchars[ch >> 4];
293: *buf++ = hexchars[ch & 15];
294: }
295: } else {
296: u_short s;
297: u_short *mp = (u_short *)mem;
298:
299: for (count >>= 1; --count >= 0; ) {
300: s = *mp++;
301: *buf++ = hexchars[(s >> 12) & 15];
302: *buf++ = hexchars[(s >> 8) & 15];
303: *buf++ = hexchars[(s >> 4) & 15];
304: *buf++ = hexchars[s & 15];
305: }
306: }
307: *buf = 0;
308: return (buf);
309: }
310:
311: /*
312: * Convert the hex array pointed to by buf into binary to be placed in mem.
313: * Return a pointer to next char in buf.
314: */
315: static char *
316: hex2mem(char *buf, char *mem, int count)
317: {
318: int i;
319: unsigned char ch;
320:
321: for (i = 0; i < count; ++i) {
322: ch = hex(*buf++) << 4;
323: ch = ch + hex(*buf++);
324: *mem++ = ch;
325: }
326: return (buf);
327: }
328:
329: /*
330: * Translate a trap number into a unix compatible signal value.
331: * (gdb only understands unix signal numbers).
332: */
333: static int
334: computeSignal(int type)
335: {
336: int sigval;
337:
338: switch (type &~ USER) {
339: case T_BUSERR:
340: sigval = SIGBUS;
341: break; /* bus error */
342: case T_ADDRERR:
343: sigval = SIGBUS;
344: break; /* address error */
345: case T_ILLINST:
346: sigval = SIGILL;
347: break; /* illegal instruction */
348: case T_ZERODIV:
349: sigval = SIGFPE;
350: break; /* zero divide */
351: case T_CHKINST:
352: sigval = SIGFPE;
353: break; /* chk instruction */
354: case T_TRAPVINST:
355: sigval = SIGFPE;
356: break; /* trapv instruction */
357: case T_PRIVINST:
358: sigval = SIGILL;
359: break; /* privilege violation */
360: case T_TRACE:
361: sigval = SIGTRAP;
362: break; /* trace trap */
363: case T_MMUFLT:
364: sigval = SIGSEGV;
365: break;
366: case T_SSIR:
367: sigval = SIGSEGV;
368: break;
369: case T_FMTERR:
370: sigval = SIGILL;
371: break;
372: case T_FPERR:
373: sigval = SIGFPE;
374: break;
375: case T_COPERR:
376: sigval = SIGFPE;
377: break;
378: case T_ASTFLT:
379: sigval = SIGINT;
380: break;
381: case T_TRAP15:
382: sigval = SIGIOT;
383: break;
384: default:
385: sigval = SIGEMT;
386: break;
387: }
388: return (sigval);
389: }
390:
391: #define RESPOND(str) (bcopy(str, outbuffer, sizeof(str)))
392:
393: /*
394: * This function does all command procesing for interfacing to
395: * a remote gdb.
396: */
397: int
398: kgdb_trap(int type, unsigned code, unsigned v, struct frame *frame)
399: {
400: int sigval;
401: int addr, length;
402: char *ptr;
403:
404: if (kgdb_dev < 0)
405: /* not debugging */
406: return (0);
407:
408: if (kgdb_debug)
409: printf("type=%d, code=%d, vector=0x%x, pc=0x%x, sr=0x%x\n",
410: type, code, frame->f_vector, frame->f_pc, frame->f_sr);
411:
412: /* reply to host that an exception has occurred */
413: sigval = computeSignal(type);
414: outbuffer[0] = 'S';
415: (void)val2hex(&outbuffer[1], sigval, 2);
416: putpacket(outbuffer);
417:
418: while (1) {
419: outbuffer[0] = 0;
420: getpacket(inbuffer);
421: ptr = inbuffer;
422: switch (*ptr++) {
423: case '?':
424: outbuffer[0] = 'S';
425: (void)val2hex(&outbuffer[1], sigval, 2);
426: break;
427: case 'g': /* return the value of the CPU registers */
428: ptr = outbuffer;
429: if (type & USER)
430: ptr = mem2hex(ptr, (char *)frame->f_regs,
431: sizeof(frame->f_regs));
432: else {
433: ptr = mem2hex(ptr, (char *)frame->f_regs,
434: sizeof(frame->f_regs) - 4);
435: addr = (int)&frame->f_pc -
436: frame_bytes[frame->f_format];
437: ptr = mem2hex(ptr, (char *)&addr, sizeof(addr));
438: }
439: addr = frame->f_sr;
440: ptr = mem2hex(ptr, (char *)&addr, sizeof(addr));
441: ptr = mem2hex(ptr, (char *)&frame->f_pc,
442: sizeof(frame->f_pc));
443: break;
444: case 'G': /* set the value of the CPU registers */
445: ptr = hex2mem(ptr, (char *)frame->f_regs,
446: sizeof(frame->f_regs) - 4);
447: ptr = hex2mem(ptr, (char *)&addr, sizeof(addr));
448: ptr = hex2mem(ptr, (char *)&addr, sizeof(addr));
449: frame->f_sr = addr;
450: ptr = hex2mem(ptr, (char *)&frame->f_pc,
451: sizeof(frame->f_pc));
452: RESPOND("OK");
453: break;
454:
455: /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
456: case 'm':
457: ptr = hex2val(ptr, &addr, 8);
458: if (*ptr++ != ',') {
459: RESPOND("E01");
460: debug_error("malformed read memory cmd: %s\n",
461: inbuffer);
462: break;
463: }
464: ptr = hex2val(ptr, &length, 8);
465: if (length <= 0 || length >= BUFMAX*2) {
466: RESPOND("E02");
467: if (kgdb_debug)
468: printf("bad read memory length: %d\n",
469: length);
470: break;
471: }
472: if (! kernacc(addr, length, B_READ)) {
473: RESPOND("E03");
474: if (kgdb_debug)
475: printf("read access violation addr 0x%x len %d\n", addr, length);
476: break;
477: }
478: (void)mem2hex(outbuffer, (char *)addr, length);
479: break;
480:
481: /*
482: * MAA..AA,LLLL: Write LLLL bytes at address AA.AA
483: * return OK
484: */
485: case 'M':
486: ptr = hex2val(ptr, &addr, 8);
487: if (*ptr++ != ',') {
488: RESPOND("E01");
489: debug_error("malformed write memory cmd: %s\n",
490: inbuffer);
491: break;
492: }
493: ptr = hex2val(ptr, &length, 8);
494: if (*ptr++ != ':') {
495: RESPOND("E01");
496: debug_error("malformed write memory cmd: %s\n",
497: inbuffer);
498: break;
499: }
500: if (length <= 0 || length >= BUFMAX*2 - 32) {
501: RESPOND("E02");
502: if (kgdb_debug)
503: printf("bad write memory length: %d\n",
504: length);
505: break;
506: }
507: if (! kernacc(addr, length, B_READ)) {
508: RESPOND("E03");
509: if (kgdb_debug)
510: printf("write access violation addr 0x%x len %d\n", addr, length);
511: break;
512: }
513: if (! kernacc(addr, length, B_WRITE))
514: chgkprot(addr, length, B_WRITE);
515: (void)hex2mem(ptr, (char *)addr, length);
516: RESPOND("OK");
517: break;
518:
519: /*
520: * cAA..AA Continue at address AA..AA
521: * sAA..AA Step one instruction from AA..AA
522: * (addresses optional)
523: */
524: case 'c':
525: case 's':
526: /*
527: * try to read optional start address.
528: */
529: if (ptr != hex2val(ptr, &addr, 8)) {
530: frame->f_pc = addr;
531: if (kgdb_debug)
532: printf("new pc = 0x%x\n", addr);
533: }
534: /* deal with the trace bit */
535: if (inbuffer[0] == 's')
536: frame->f_sr |= PSL_T;
537: else
538: frame->f_sr &=~ PSL_T;
539:
540: if (kgdb_debug)
541: printf("restarting at 0x%x\n", frame->f_pc);
542:
543: return (1);
544:
545: /* kill the program (same as continue for now) */
546: case 'k':
547: return (1);
548: }
549: /* reply to the request */
550: putpacket(outbuffer);
551: }
552: }
553: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.