Annotation of XNU/osfmk/kdp/kdp.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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