|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1993 NeXT Computer, Inc. All rights reserved.
24: *
25: * kdp.c -- Kernel Debugging Protocol.
26: *
27: */
28:
29: #include <mach/mach_types.h>
30: #include <kern/debug.h>
31:
32: #include <kdp/kdp_internal.h>
33: #include <kdp/kdp_private.h>
34:
35: int kdp_vm_read( caddr_t, caddr_t, unsigned int);
36: int kdp_vm_write( caddr_t, caddr_t, unsigned int);
37:
38: #define DO_ALIGN 1 /* align all packet data accesses */
39:
40: #define KDP_TEST_HARNESS 0
41: #if KDP_TEST_HARNESS
42: #define dprintf(x) kprintf x
43: #else
44: #define dprintf(x)
45: #endif
46:
47: static kdp_dispatch_t
48: dispatch_table[KDP_TERMINATION - KDP_CONNECT + 1] =
49: {
50: /* 0 */ kdp_connect,
51: /* 1 */ kdp_disconnect,
52: /* 2 */ kdp_hostinfo,
53: /* 3 */ kdp_regions,
54: /* 4 */ kdp_maxbytes,
55: /* 5 */ kdp_readmem,
56: /* 6 */ kdp_writemem,
57: /* 7 */ kdp_readregs,
58: /* 8 */ kdp_writeregs,
59: /* 9 */ kdp_unknown,
60: /* A */ kdp_unknown,
61: /* B */ kdp_suspend,
62: /* C */ kdp_resumecpus,
63: /* D */ kdp_unknown,
64: /* E */ kdp_unknown,
65: };
66:
67: kdp_glob_t kdp;
68: int kdp_flag=0;
69:
70: boolean_t
71: kdp_packet(
72: unsigned char *pkt,
73: int *len,
74: unsigned short *reply_port
75: )
76: {
77: static unsigned aligned_pkt[1538/sizeof(unsigned)+1]; // max ether pkt
78: kdp_pkt_t *rd = (kdp_pkt_t *)&aligned_pkt;
79: int plen = *len;
80: unsigned int req;
81: boolean_t ret;
82:
83: #if DO_ALIGN
84: bcopy((char *)pkt, (char *)rd, sizeof(aligned_pkt));
85: #else
86: rd = (kdp_pkt_t *)pkt;
87: #endif
88: if (plen < sizeof (rd->hdr) || rd->hdr.len != plen) {
89: printf("kdp_packet bad len pkt %d hdr %d\n", plen, rd->hdr.len);
90:
91: return (FALSE);
92: }
93:
94: if (rd->hdr.is_reply) {
95: printf("kdp_packet reply recvd req %x seq %x\n",
96: rd->hdr.request, rd->hdr.seq);
97:
98: return (FALSE);
99: }
100:
101: req = rd->hdr.request;
102: if (req < KDP_CONNECT || req > KDP_TERMINATION) {
103: printf("kdp_packet bad request %x len %d seq %x key %x\n",
104: rd->hdr.request, rd->hdr.len, rd->hdr.seq, rd->hdr.key);
105:
106: return (FALSE);
107: }
108:
109: ret = ((*dispatch_table[req - KDP_CONNECT])(rd, len, reply_port));
110: #if DO_ALIGN
111: bcopy((char *)rd, (char *) pkt, *len);
112: #endif
113: return ret;
114: }
115:
116: static boolean_t
117: kdp_unknown(
118: kdp_pkt_t *pkt,
119: int *len,
120: unsigned short *reply_port
121: )
122: {
123: kdp_pkt_t *rd = (kdp_pkt_t *)pkt;
124:
125: printf("kdp_unknown request %x len %d seq %x key %x\n",
126: rd->hdr.request, rd->hdr.len, rd->hdr.seq, rd->hdr.key);
127:
128: return (FALSE);
129: }
130:
131: static boolean_t
132: kdp_connect(
133: kdp_pkt_t *pkt,
134: int *len,
135: unsigned short *reply_port
136: )
137: {
138: kdp_connect_req_t *rq = &pkt->connect_req;
139: int plen = *len;
140: kdp_connect_reply_t *rp = &pkt->connect_reply;
141:
142: if (plen < sizeof (*rq))
143: return (FALSE);
144:
145: dprintf(("kdp_connect seq %x greeting %s\n", rq->hdr.seq, rq->greeting));
146:
147: if (kdp.is_conn) {
148: if (rq->hdr.seq == kdp.conn_seq) /* duplicate request */
149: rp->error = KDPERR_NO_ERROR;
150: else
151: rp->error = KDPERR_ALREADY_CONNECTED;
152: }
153: else {
154: kdp.reply_port = rq->req_reply_port;
155: kdp.exception_port = rq->exc_note_port;
156: kdp.is_conn = TRUE;
157: kdp.conn_seq = rq->hdr.seq;
158:
159: rp->error = KDPERR_NO_ERROR;
160: }
161:
162: rp->hdr.is_reply = 1;
163: rp->hdr.len = sizeof (*rp);
164:
165: *reply_port = kdp.reply_port;
166: *len = rp->hdr.len;
167:
168: if (current_debugger == KDP_CUR_DB)
169: active_debugger=1;
170:
171: return (TRUE);
172: }
173:
174: static boolean_t
175: kdp_disconnect(
176: kdp_pkt_t *pkt,
177: int *len,
178: unsigned short *reply_port
179: )
180: {
181: kdp_disconnect_req_t *rq = &pkt->disconnect_req;
182: int plen = *len;
183: kdp_disconnect_reply_t *rp = &pkt->disconnect_reply;
184:
185: if (plen < sizeof (*rq))
186: return (FALSE);
187:
188: if (!kdp.is_conn)
189: return (FALSE);
190:
191: dprintf(("kdp_disconnect\n"));
192:
193: *reply_port = kdp.reply_port;
194:
195: kdp.reply_port = kdp.exception_port = 0;
196: kdp.is_halted = kdp.is_conn = FALSE;
197: kdp.exception_seq = kdp.conn_seq = 0;
198:
199: rp->hdr.is_reply = 1;
200: rp->hdr.len = sizeof (*rp);
201:
202: *len = rp->hdr.len;
203:
204: if (current_debugger == KDP_CUR_DB)
205: active_debugger=0;
206:
207: return (TRUE);
208: }
209:
210: static boolean_t
211: kdp_hostinfo(
212: kdp_pkt_t *pkt,
213: int *len,
214: unsigned short *reply_port
215: )
216: {
217: kdp_hostinfo_req_t *rq = &pkt->hostinfo_req;
218: int plen = *len;
219: kdp_hostinfo_reply_t *rp = &pkt->hostinfo_reply;
220:
221: if (plen < sizeof (*rq))
222: return (FALSE);
223:
224: rp->hdr.is_reply = 1;
225: rp->hdr.len = sizeof (*rp);
226:
227: kdp_machine_hostinfo(&rp->hostinfo);
228:
229: *reply_port = kdp.reply_port;
230: *len = rp->hdr.len;
231:
232: return (TRUE);
233: }
234:
235: static boolean_t
236: kdp_suspend(
237: kdp_pkt_t *pkt,
238: int *len,
239: unsigned short *reply_port
240: )
241: {
242: kdp_suspend_req_t *rq = &pkt->suspend_req;
243: int plen = *len;
244: kdp_suspend_reply_t *rp = &pkt->suspend_reply;
245:
246: if (plen < sizeof (*rq))
247: return (FALSE);
248:
249: rp->hdr.is_reply = 1;
250: rp->hdr.len = sizeof (*rp);
251:
252: dprintf(("kdp_suspend\n"));
253:
254: kdp.is_halted = TRUE;
255:
256: *reply_port = kdp.reply_port;
257: *len = rp->hdr.len;
258:
259: return (TRUE);
260: }
261:
262: static boolean_t
263: kdp_resumecpus(
264: kdp_pkt_t *pkt,
265: int *len,
266: unsigned short *reply_port
267: )
268: {
269: kdp_resumecpus_req_t *rq = &pkt->resumecpus_req;
270: int plen = *len;
271: kdp_resumecpus_reply_t *rp = &pkt->resumecpus_reply;
272:
273: if (plen < sizeof (*rq))
274: return (FALSE);
275:
276: rp->hdr.is_reply = 1;
277: rp->hdr.len = sizeof (*rp);
278:
279: dprintf(("kdp_resumecpus %x\n", rq->cpu_mask));
280:
281: kdp.is_halted = FALSE;
282:
283: *reply_port = kdp.reply_port;
284: *len = rp->hdr.len;
285:
286: return (TRUE);
287: }
288:
289: static boolean_t
290: kdp_writemem(
291: kdp_pkt_t *pkt,
292: int *len,
293: unsigned short *reply_port
294: )
295: {
296: kdp_writemem_req_t *rq = &pkt->writemem_req;
297: int plen = *len;
298: kdp_writemem_reply_t *rp = &pkt->writemem_reply;
299: int cnt;
300:
301: if (plen < sizeof (*rq))
302: return (FALSE);
303:
304: if (rq->nbytes > MAX_KDP_DATA_SIZE)
305: rp->error = KDPERR_BAD_NBYTES;
306: else {
307: dprintf(("kdp_writemem addr %x size %d\n", rq->address, rq->nbytes));
308:
309: cnt = kdp_vm_write((caddr_t)rq->data, (caddr_t)rq->address, rq->nbytes);
310: rp->error = KDPERR_NO_ERROR;
311: }
312:
313: rp->hdr.is_reply = 1;
314: rp->hdr.len = sizeof (*rp);
315:
316: *reply_port = kdp.reply_port;
317: *len = rp->hdr.len;
318:
319: return (TRUE);
320: }
321:
322: static boolean_t
323: kdp_readmem(
324: kdp_pkt_t *pkt,
325: int *len,
326: unsigned short *reply_port
327: )
328: {
329: kdp_readmem_req_t *rq = &pkt->readmem_req;
330: int plen = *len;
331: kdp_readmem_reply_t *rp = &pkt->readmem_reply;
332: int cnt;
333:
334: if (plen < sizeof (*rq))
335: return (FALSE);
336:
337: rp->hdr.is_reply = 1;
338: rp->hdr.len = sizeof (*rp);
339:
340: if (rq->nbytes > MAX_KDP_DATA_SIZE)
341: rp->error = KDPERR_BAD_NBYTES;
342: else {
343: unsigned int n = rq->nbytes;
344:
345: dprintf(("kdp_readmem addr %x size %d\n", rq->address, rq->nbytes));
346:
347: cnt = kdp_vm_read((caddr_t)rq->address, (caddr_t)rp->data, rq->nbytes);
348: rp->error = KDPERR_NO_ERROR;
349:
350: rp->hdr.len += cnt;
351: }
352:
353: *reply_port = kdp.reply_port;
354: *len = rp->hdr.len;
355:
356: return (TRUE);
357: }
358:
359: static boolean_t
360: kdp_maxbytes(
361: kdp_pkt_t *pkt,
362: int *len,
363: unsigned short *reply_port
364: )
365: {
366: kdp_maxbytes_req_t *rq = &pkt->maxbytes_req;
367: int plen = *len;
368: kdp_maxbytes_reply_t *rp = &pkt->maxbytes_reply;
369:
370: if (plen < sizeof (*rq))
371: return (FALSE);
372:
373: rp->hdr.is_reply = 1;
374: rp->hdr.len = sizeof (*rp);
375:
376: dprintf(("kdp_maxbytes\n"));
377:
378: rp->max_bytes = MAX_KDP_DATA_SIZE;
379:
380: *reply_port = kdp.reply_port;
381: *len = rp->hdr.len;
382:
383: return (TRUE);
384: }
385:
386: static boolean_t
387: kdp_regions(
388: kdp_pkt_t *pkt,
389: int *len,
390: unsigned short *reply_port
391: )
392: {
393: kdp_regions_req_t *rq = &pkt->regions_req;
394: int plen = *len;
395: kdp_regions_reply_t *rp = &pkt->regions_reply;
396: kdp_region_t *r;
397:
398: if (plen < sizeof (*rq))
399: return (FALSE);
400:
401: rp->hdr.is_reply = 1;
402: rp->hdr.len = sizeof (*rp);
403:
404: dprintf(("kdp_regions\n"));
405:
406: r = rp->regions;
407: rp->nregions = 0;
408:
409: (vm_offset_t)r->address = 0;
410: r->nbytes = 0xffffffff;
411:
412: r->protection = VM_PROT_ALL; r++; rp->nregions++;
413:
414: rp->hdr.len += rp->nregions * sizeof (kdp_region_t);
415:
416: *reply_port = kdp.reply_port;
417: *len = rp->hdr.len;
418:
419: return (TRUE);
420: }
421:
422: static boolean_t
423: kdp_writeregs(
424: kdp_pkt_t *pkt,
425: int *len,
426: unsigned short *reply_port
427: )
428: {
429: kdp_writeregs_req_t *rq = &pkt->writeregs_req;
430: int plen = *len;
431: int size;
432: kdp_writeregs_reply_t *rp = &pkt->writeregs_reply;
433:
434: if (plen < sizeof (*rq))
435: return (FALSE);
436:
437: size = rq->hdr.len - sizeof(kdp_hdr_t) - sizeof(unsigned int);
438: rp->error = kdp_machine_write_regs(rq->cpu, rq->flavor, rq->data, &size);
439:
440: rp->hdr.is_reply = 1;
441: rp->hdr.len = sizeof (*rp);
442:
443: *reply_port = kdp.reply_port;
444: *len = rp->hdr.len;
445:
446: return (TRUE);
447: }
448:
449: static boolean_t
450: kdp_readregs(
451: kdp_pkt_t *pkt,
452: int *len,
453: unsigned short *reply_port
454: )
455: {
456: kdp_readregs_req_t *rq = &pkt->readregs_req;
457: int plen = *len;
458: kdp_readregs_reply_t *rp = &pkt->readregs_reply;
459: int size;
460:
461: if (plen < sizeof (*rq))
462: return (FALSE);
463:
464: rp->hdr.is_reply = 1;
465: rp->hdr.len = sizeof (*rp);
466:
467: rp->error = kdp_machine_read_regs(rq->cpu, rq->flavor, rp->data, &size);
468: rp->hdr.len += size;
469:
470: *reply_port = kdp.reply_port;
471: *len = rp->hdr.len;
472:
473: return (TRUE);
474: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.