Annotation of kernel/kern/kdp.c, revision 1.1.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.