Annotation of kernel/kern/kdp.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.