|
|
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.