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