Annotation of XNU/bsd/kern/kdebug.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: #include <kern/cpu_number.h>
                     23: 
                     24: #include <machine/spl.h>
                     25: 
                     26: #define HZ      100
                     27: #include <mach/clock_types.h>
                     28: #include <mach/mach_types.h>
                     29: 
                     30: #include <sys/kdebug.h>
                     31: #include <sys/errno.h>
                     32: #include <sys/param.h>         /* for splhigh */
                     33: #include <sys/proc.h>
                     34: #include <sys/vm.h>
                     35: #include <sys/sysctl.h>
                     36: 
                     37: #include <kern/thread.h>
                     38: #include <kern/task.h>
                     39: #include <vm/vm_kern.h>
                     40: 
                     41: /* kd_buf kd_buffer[kd_bufsize/sizeof(kd_buf)]; */
                     42: kd_buf * kd_bufptr;
                     43: unsigned int kd_buftomem=0;
                     44: kd_buf * kd_buffer=0;
                     45: kd_buf * kd_buflast;
                     46: kd_buf * kd_readlast;
                     47: unsigned int nkdbufs = 8192;
                     48: unsigned int kd_bufsize = 0;
                     49: unsigned int kdebug_flags = 0;
                     50: unsigned int kdebug_enable=0;
                     51: unsigned int kdebug_nolog=1;
                     52: unsigned int kdlog_beg=0;
                     53: unsigned int kdlog_end=0;
                     54: unsigned int kdlog_value1=0;
                     55: unsigned int kdlog_value2=0;
                     56: unsigned int kdlog_value3=0;
                     57: unsigned int kdlog_value4=0;
                     58: 
                     59: kd_threadmap *kd_mapptr = 0;
                     60: unsigned int kd_mapsize = 0;
                     61: unsigned int kd_mapcount = 0;
                     62: unsigned int kd_maptomem = 0;
                     63: 
                     64: pid_t global_state_pid = -1;       /* Used to control exclusive use of kd_buffer */
                     65: 
                     66: #define DBG_FUNC_MASK 0xfffffffc
                     67: 
                     68: extern void PE_get_timebase(unsigned long long *);
                     69: 
                     70: #ifdef ppc
                     71: extern natural_t rtclock_decrementer_min;
                     72: #endif /* ppc */
                     73: 
                     74: struct kdebug_args {
                     75:   int code;
                     76:   int arg1;
                     77:   int arg2;
                     78:   int arg3;
                     79:   int arg4;
                     80:   int arg5;
                     81: };
                     82: 
                     83: struct krt
                     84: {
                     85:   kd_threadmap *map;    /* pointer to the map buffer */
                     86:   int count;
                     87:   int maxcount;
                     88:   struct proc *p;
                     89: };
                     90: 
                     91: typedef struct krt krt_t;
                     92: 
                     93: /* Support syscall SYS_kdebug_trace */
                     94: kdebug_trace(p, uap, retval)
                     95:      struct proc *p;
                     96:      struct kdebug_args *uap;
                     97:      register_t *retval;
                     98: {
                     99:   if (kdebug_nolog)
                    100:     return(EINVAL);
                    101:   
                    102:   kernel_debug(uap->code, uap->arg1, uap->arg2, uap->arg3, uap->arg4, 0);
                    103:   return(0);
                    104: }
                    105: 
                    106: 
                    107: void
                    108: kernel_debug(debugid, arg1, arg2, arg3, arg4, arg5)
                    109: unsigned int debugid, arg1, arg2, arg3, arg4, arg5;
                    110: {
                    111:        kd_buf * kd;
                    112:        struct proc *curproc;
                    113:        int      s;
                    114: 
                    115:        s = ml_set_interrupts_enabled(FALSE);
                    116: 
                    117:        if (kdebug_nolog)
                    118:          {
                    119:            ml_set_interrupts_enabled(s);
                    120:            return;
                    121:          }
                    122: 
                    123:        if (kdebug_flags & KDBG_PIDCHECK)
                    124:          {
                    125:            /* If kdebug flag is not set for current proc, return  */
                    126:            curproc = current_proc();
                    127:            if ((curproc && !(curproc->p_flag & P_KDEBUG)) &&
                    128:                ((debugid&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED, 0) | DBG_FUNC_NONE)))
                    129:              {
                    130:                ml_set_interrupts_enabled(s);
                    131:                return;
                    132:              }
                    133:          }
                    134:        else if (kdebug_flags & KDBG_PIDEXCLUDE)
                    135:          {
                    136:            /* If kdebug flag is set for current proc, return  */
                    137:            curproc = current_proc();
                    138:            if ((curproc && (curproc->p_flag & P_KDEBUG)) &&
                    139:                ((debugid&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED, 0) | DBG_FUNC_NONE)))
                    140:              {
                    141:                ml_set_interrupts_enabled(s);
                    142:                return;
                    143:              }
                    144:          }
                    145: 
                    146:        if (kdebug_flags & KDBG_RANGECHECK)
                    147:          {
                    148:            if ((debugid < kdlog_beg) || (debugid > kdlog_end) 
                    149:                && (debugid >> 24 != DBG_TRACE))
                    150:              {
                    151:                ml_set_interrupts_enabled(s);
                    152:                return;
                    153:              }
                    154:          }
                    155:        else if (kdebug_flags & KDBG_VALCHECK)
                    156:          {
                    157:            if ((debugid & DBG_FUNC_MASK) != kdlog_value1 &&
                    158:                (debugid & DBG_FUNC_MASK) != kdlog_value2 &&
                    159:                (debugid & DBG_FUNC_MASK) != kdlog_value3 &&
                    160:                (debugid & DBG_FUNC_MASK) != kdlog_value4 &&
                    161:                (debugid >> 24 != DBG_TRACE))
                    162:              {
                    163:                ml_set_interrupts_enabled(s);
                    164:                return;
                    165:              }
                    166:          }
                    167:        kd = kd_bufptr;
                    168:        kd->debugid = debugid;
                    169:        kd->arg1 = arg1;
                    170:        kd->arg2 = arg2;
                    171:        kd->arg3 = arg3;
                    172:        kd->arg4 = arg4;
                    173:        kd->arg5 = (int)current_thread();
                    174:        PE_get_timebase((unsigned long long *)&kd->timestamp);
                    175:        kd_bufptr++;
                    176: 
                    177:        if (kd_bufptr >= kd_buflast)
                    178:                kd_bufptr = kd_buffer;
                    179:        if (kd_bufptr == kd_readlast) {
                    180:                if (kdebug_flags & KDBG_NOWRAP)
                    181:                        kdebug_nolog = 1;
                    182:                kdebug_flags |= KDBG_WRAPPED;
                    183:        }
                    184:        ml_set_interrupts_enabled(s);
                    185: }
                    186: 
                    187: void
                    188: kernel_debug1(debugid, arg1, arg2, arg3, arg4, arg5)
                    189: unsigned int debugid, arg1, arg2, arg3, arg4, arg5;
                    190: {
                    191:        kd_buf * kd;
                    192:        struct proc *curproc;
                    193:        int      s;
                    194: 
                    195:        s = ml_set_interrupts_enabled(FALSE);
                    196: 
                    197:        if (kdebug_nolog)
                    198:          {
                    199:            ml_set_interrupts_enabled(s);
                    200:            return;
                    201:          }
                    202: 
                    203:        if (kdebug_flags & KDBG_PIDCHECK)
                    204:          {
                    205:            /* If kdebug flag is not set for current proc, return  */
                    206:            curproc = current_proc();
                    207:            if ((curproc && !(curproc->p_flag & P_KDEBUG)) &&
                    208:                ((debugid&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED, 0) | DBG_FUNC_NONE)))
                    209:              {
                    210:                ml_set_interrupts_enabled(s);
                    211:                return;
                    212:              }
                    213:          }
                    214:        else if (kdebug_flags & KDBG_PIDEXCLUDE)
                    215:          {
                    216:            /* If kdebug flag is set for current proc, return  */
                    217:            curproc = current_proc();
                    218:            if ((curproc && (curproc->p_flag & P_KDEBUG)) &&
                    219:                ((debugid&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED, 0) | DBG_FUNC_NONE)))
                    220:              {
                    221:                ml_set_interrupts_enabled(s);
                    222:                return;
                    223:              }
                    224:          }
                    225: 
                    226:        if (kdebug_flags & KDBG_RANGECHECK)
                    227:          {
                    228:            if ((debugid < kdlog_beg) || (debugid > kdlog_end)
                    229:                && (debugid >> 24 != DBG_TRACE))
                    230:              {
                    231:                ml_set_interrupts_enabled(s);
                    232:                return;
                    233:              }
                    234:          }
                    235:        else if (kdebug_flags & KDBG_VALCHECK)
                    236:          {
                    237:            if ((debugid & DBG_FUNC_MASK) != kdlog_value1 &&
                    238:                (debugid & DBG_FUNC_MASK) != kdlog_value2 &&
                    239:                (debugid & DBG_FUNC_MASK) != kdlog_value3 &&
                    240:                (debugid & DBG_FUNC_MASK) != kdlog_value4 &&
                    241:                (debugid >> 24 != DBG_TRACE))
                    242:              {
                    243:                ml_set_interrupts_enabled(s);
                    244:                return;
                    245:              }
                    246:          }
                    247: 
                    248:        kd = kd_bufptr;
                    249:        kd->debugid = debugid;
                    250:        kd->arg1 = arg1;
                    251:        kd->arg2 = arg2;
                    252:        kd->arg3 = arg3;
                    253:        kd->arg4 = arg4;
                    254:        kd->arg5 = arg5;
                    255:        PE_get_timebase((unsigned long long *)&kd->timestamp);
                    256:        kd_bufptr++;
                    257: 
                    258:        if (kd_bufptr >= kd_buflast)
                    259:                kd_bufptr = kd_buffer;
                    260:        if (kd_bufptr == kd_readlast) {
                    261:                if (kdebug_flags & KDBG_NOWRAP)
                    262:                        kdebug_nolog = 1;
                    263:                kdebug_flags |= KDBG_WRAPPED;
                    264:        }
                    265:        ml_set_interrupts_enabled(s);
                    266: }
                    267: 
                    268: 
                    269: kdbg_bootstrap()
                    270: {
                    271:        kd_bufsize = nkdbufs * sizeof(kd_buf);
                    272:        if (kmem_alloc(kernel_map, &kd_buftomem,
                    273:                              (vm_size_t)kd_bufsize) == KERN_SUCCESS) 
                    274:        kd_buffer = (kd_buf *) kd_buftomem;
                    275:        else kd_buffer= (kd_buf *) 0;
                    276:        kdebug_flags &= ~KDBG_WRAPPED;
                    277:        if (kd_buffer) {
                    278:                kdebug_flags |= (KDBG_INIT | KDBG_BUFINIT);
                    279:                kd_bufptr = kd_buffer;
                    280:                kd_buflast = &kd_bufptr[nkdbufs];
                    281:                kd_readlast = kd_bufptr;
                    282:                return(0);
                    283:        } else {
                    284:                kd_bufsize=0;
                    285:                kdebug_flags &= ~(KDBG_INIT | KDBG_BUFINIT);
                    286:                return(EINVAL);
                    287:        }
                    288:        
                    289: }
                    290: 
                    291: kdbg_reinit()
                    292: {
                    293:     int x;
                    294:     int ret=0;
                    295: 
                    296:     kdebug_enable = 0;
                    297:     kdebug_nolog = 1;
                    298: 
                    299:     if ((kdebug_flags & KDBG_INIT) && (kdebug_flags & KDBG_BUFINIT) && kd_bufsize && kd_buffer)
                    300:         kmem_free(kernel_map, (char *)kd_buffer, kd_bufsize);
                    301: 
                    302:     if ((kdebug_flags & KDBG_MAPINIT) && kd_mapsize && kd_mapptr)
                    303:       {
                    304:        kmem_free(kernel_map, (char *)kd_mapptr, kd_mapsize);
                    305:        kdebug_flags &= ~KDBG_MAPINIT;
                    306:        kd_mapsize = 0;
                    307:        kd_mapptr = (kd_threadmap *) 0;
                    308:        kd_mapcount = 0;
                    309:       }  
                    310: 
                    311:     ret= kdbg_bootstrap();
                    312: 
                    313:     return(ret);
                    314: }
                    315: 
                    316: void kdbg_trace_string(struct proc *proc, long *arg1, long *arg2, long *arg3, long *arg4)
                    317: {
                    318:     int i;
                    319:     char *dbg_nameptr; 
                    320:     int dbg_namelen;
                    321:     long dbg_parms[4];
                    322: 
                    323:     if (!proc)
                    324:       {
                    325:        *arg1 = 0;
                    326:        *arg2 = 0;
                    327:        *arg3 = 0;
                    328:        *arg4 = 0;
                    329:        return;
                    330:       }
                    331: 
                    332:     /* Collect the pathname for tracing */
                    333:     dbg_nameptr = proc->p_comm;
                    334:     dbg_namelen = strlen(proc->p_comm);
                    335:     dbg_parms[0]=0L;
                    336:     dbg_parms[1]=0L;
                    337:     dbg_parms[2]=0L;
                    338:     dbg_parms[3]=0L;
                    339:   
                    340:     if(dbg_namelen > sizeof(dbg_parms))
                    341:       dbg_namelen = sizeof(dbg_parms);
                    342:     
                    343:     for(i=0;dbg_namelen > 0; i++)
                    344:       {
                    345:        dbg_parms[i]=*(long*)dbg_nameptr;
                    346:        dbg_nameptr += sizeof(long);
                    347:        dbg_namelen -= sizeof(long);
                    348:       }
                    349: 
                    350:     *arg1=dbg_parms[0];
                    351:     *arg2=dbg_parms[1];
                    352:     *arg3=dbg_parms[2];
                    353:     *arg4=dbg_parms[3];
                    354: }
                    355: 
                    356: kdbg_resolve_map(thread_act_t th_act, krt_t *t)
                    357: {
                    358:   kd_threadmap *mapptr;
                    359: 
                    360:   if(t->count < t->maxcount)
                    361:     {
                    362:       mapptr=&t->map[t->count];
                    363:       mapptr->thread  = (unsigned int)getshuttle_thread(th_act);
                    364:       mapptr->valid = 1;
                    365:       (void) strncpy (mapptr->command, t->p->p_comm,
                    366:                      sizeof(t->p->p_comm)-1);
                    367:       mapptr->command[sizeof(t->p->p_comm)-1] = '\0';
                    368:       t->count++;
                    369:     }
                    370: }
                    371: 
                    372: void kdbg_mapinit()
                    373: {
                    374:        struct proc *p;
                    375:        struct krt akrt;
                    376: 
                    377:         if (kdebug_flags & KDBG_MAPINIT)
                    378:          return;
                    379: 
                    380:        /* Calculate size of thread map buffer */
                    381:        for (p = allproc.lh_first, kd_mapcount=0; p; 
                    382:             p = p->p_list.le_next)
                    383:          {
                    384:            kd_mapcount += get_task_numacts((task_t)p->task);
                    385:          }
                    386: 
                    387:        kd_mapsize = kd_mapcount * sizeof(kd_threadmap);
                    388:        if((kmem_alloc(kernel_map, & kd_maptomem,
                    389:                       (vm_size_t)kd_mapsize) == KERN_SUCCESS))
                    390:            kd_mapptr = (kd_threadmap *) kd_maptomem;
                    391:        else
                    392:            kd_mapptr = (kd_threadmap *) 0;
                    393: 
                    394:        if (kd_mapptr)
                    395:          {
                    396:            kdebug_flags |= KDBG_MAPINIT;
                    397:            /* Initialize thread map data */
                    398:            akrt.map = kd_mapptr;
                    399:            akrt.count = 0;
                    400:            akrt.maxcount = kd_mapcount;
                    401:            
                    402:            for (p = allproc.lh_first; p; p = p->p_list.le_next)
                    403:              {
                    404:                akrt.p = p;
                    405:                task_act_iterate_wth_args((task_t)p->task, kdbg_resolve_map, &akrt);
                    406:              }     
                    407:          }
                    408: }
                    409: 
                    410: kdbg_clear()
                    411: {
                    412: int x;
                    413: 
                    414:         /* Clean up the trace buffer */ 
                    415:         global_state_pid = -1;
                    416:        kdebug_enable = 0;
                    417:        kdebug_nolog = 1;
                    418:        kdebug_flags &= ~KDBG_BUFINIT;
                    419:        kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    420:        kdebug_flags &= ~(KDBG_NOWRAP | KDBG_RANGECHECK | KDBG_VALCHECK);
                    421:        kdebug_flags &= ~(KDBG_PIDCHECK | KDBG_PIDEXCLUDE);
                    422:        kmem_free(kernel_map, (char *)kd_buffer, kd_bufsize);
                    423:        kd_buffer = (kd_buf *)0;
                    424:        kd_bufsize = 0;
                    425: 
                    426:        /* Clean up the thread map buffer */
                    427:        kdebug_flags &= ~KDBG_MAPINIT;
                    428:        kmem_free(kernel_map, (char *)kd_mapptr, kd_mapsize);
                    429:        kd_mapptr = (kd_threadmap *) 0;
                    430:        kd_mapsize = 0;
                    431:        kd_mapcount = 0;
                    432: }
                    433: 
                    434: kdbg_setpid(kd_regtype *kdr)
                    435: {
                    436:   pid_t pid;
                    437:   int flag, ret=0;
                    438:   struct proc *p;
                    439: 
                    440:   pid = (pid_t)kdr->value1;
                    441:   flag = (int)kdr->value2;
                    442: 
                    443:   if (pid > 0)
                    444:     {
                    445:       if ((p = pfind(pid)) == NULL)
                    446:        ret = ESRCH;
                    447:       else
                    448:        {
                    449:          if (flag == 1)  /* turn on pid check for this and all pids */
                    450:            {
                    451:              kdebug_flags |= KDBG_PIDCHECK;
                    452:              kdebug_flags &= ~KDBG_PIDEXCLUDE;
                    453:              p->p_flag |= P_KDEBUG;
                    454:            }
                    455:          else  /* turn off pid check for this pid value */
                    456:            {
                    457:              /* Don't turn off all pid checking though */
                    458:              /* kdebug_flags &= ~KDBG_PIDCHECK;*/   
                    459:              p->p_flag &= ~P_KDEBUG;
                    460:            }
                    461:        }
                    462:     }
                    463:   else
                    464:     ret = EINVAL;
                    465:   return(ret);
                    466: }
                    467: 
                    468: /* This is for pid exclusion in the trace buffer */
                    469: kdbg_setpidex(kd_regtype *kdr)
                    470: {
                    471:   pid_t pid;
                    472:   int flag, ret=0;
                    473:   struct proc *p;
                    474: 
                    475:   pid = (pid_t)kdr->value1;
                    476:   flag = (int)kdr->value2;
                    477: 
                    478:   if (pid > 0)
                    479:     {
                    480:       if ((p = pfind(pid)) == NULL)
                    481:        ret = ESRCH;
                    482:       else
                    483:        {
                    484:          if (flag == 1)  /* turn on pid exclusion */
                    485:            {
                    486:              kdebug_flags |= KDBG_PIDEXCLUDE;
                    487:              kdebug_flags &= ~KDBG_PIDCHECK;
                    488:              p->p_flag |= P_KDEBUG;
                    489:            }
                    490:          else  /* turn off pid exclusion for this pid value */
                    491:            {
                    492:              /* Don't turn off all pid exclusion though */
                    493:              /* kdebug_flags &= ~KDBG_PIDEXCLUDE;*/   
                    494:              p->p_flag &= ~P_KDEBUG;
                    495:            }
                    496:        }
                    497:     }
                    498:   else
                    499:     ret = EINVAL;
                    500:   return(ret);
                    501: }
                    502: 
                    503: /* This is for setting a minimum decrementer value */
                    504: kdbg_setrtcdec(kd_regtype *kdr)
                    505: {
                    506:   int ret=0;
                    507:   natural_t decval;
                    508: 
                    509:   decval = (natural_t)kdr->value1;
                    510: 
                    511:   if (decval && decval < KDBG_MINRTCDEC)
                    512:       ret = EINVAL;
                    513: #ifdef ppc
                    514:   else
                    515:       rtclock_decrementer_min = decval;
                    516: #else
                    517:   else
                    518:     ret = EOPNOTSUPP;
                    519: #endif /* ppc */
                    520: 
                    521:   return(ret);
                    522: }
                    523: 
                    524: kdbg_setreg(kd_regtype * kdr)
                    525: {
                    526:        int i,j, ret=0;
                    527:        unsigned int val_1, val_2, val;
                    528:        switch (kdr->type) {
                    529:        
                    530:        case KDBG_CLASSTYPE :
                    531:                val_1 = (kdr->value1 & 0xff);
                    532:                val_2 = (kdr->value2 & 0xff);
                    533:                kdlog_beg = (val_1<<24);
                    534:                kdlog_end = (val_2<<24);
                    535:                kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    536:                kdebug_flags &= ~KDBG_VALCHECK;       /* Turn off specific value check  */
                    537:                kdebug_flags |= (KDBG_RANGECHECK | KDBG_CLASSTYPE);
                    538:                break;
                    539:        case KDBG_SUBCLSTYPE :
                    540:                val_1 = (kdr->value1 & 0xff);
                    541:                val_2 = (kdr->value2 & 0xff);
                    542:                val = val_2 + 1;
                    543:                kdlog_beg = ((val_1<<24) | (val_2 << 16));
                    544:                kdlog_end = ((val_1<<24) | (val << 16));
                    545:                kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    546:                kdebug_flags &= ~KDBG_VALCHECK;       /* Turn off specific value check  */
                    547:                kdebug_flags |= (KDBG_RANGECHECK | KDBG_SUBCLSTYPE);
                    548:                break;
                    549:        case KDBG_RANGETYPE :
                    550:                kdlog_beg = (kdr->value1);
                    551:                kdlog_end = (kdr->value2);
                    552:                kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    553:                kdebug_flags &= ~KDBG_VALCHECK;       /* Turn off specific value check  */
                    554:                kdebug_flags |= (KDBG_RANGECHECK | KDBG_RANGETYPE);
                    555:                break;
                    556:        case KDBG_VALCHECK:
                    557:                kdlog_value1 = (kdr->value1);
                    558:                kdlog_value2 = (kdr->value2);
                    559:                kdlog_value3 = (kdr->value3);
                    560:                kdlog_value4 = (kdr->value4);
                    561:                kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    562:                kdebug_flags &= ~KDBG_RANGECHECK;    /* Turn off range check */
                    563:                kdebug_flags |= KDBG_VALCHECK;       /* Turn on specific value check  */
                    564:                break;
                    565:        case KDBG_TYPENONE :
                    566:                kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    567:                kdlog_beg = 0;
                    568:                kdlog_end = 0;
                    569:                break;
                    570:        default :
                    571:                ret = EINVAL;
                    572:                break;
                    573:        }
                    574:        return(ret);
                    575: }
                    576: 
                    577: kdbg_getreg(kd_regtype * kdr)
                    578: {
                    579:        int i,j, ret=0;
                    580:        unsigned int val_1, val_2, val;
                    581: #if 0  
                    582:        switch (kdr->type) {
                    583:        case KDBG_CLASSTYPE :
                    584:                val_1 = (kdr->value1 & 0xff);
                    585:                val_2 = val_1 + 1;
                    586:                kdlog_beg = (val_1<<24);
                    587:                kdlog_end = (val_2<<24);
                    588:                kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    589:                kdebug_flags |= (KDBG_RANGECHECK | KDBG_CLASSTYPE);
                    590:                break;
                    591:        case KDBG_SUBCLSTYPE :
                    592:                val_1 = (kdr->value1 & 0xff);
                    593:                val_2 = (kdr->value2 & 0xff);
                    594:                val = val_2 + 1;
                    595:                kdlog_beg = ((val_1<<24) | (val_2 << 16));
                    596:                kdlog_end = ((val_1<<24) | (val << 16));
                    597:                kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    598:                kdebug_flags |= (KDBG_RANGECHECK | KDBG_SUBCLSTYPE);
                    599:                break;
                    600:        case KDBG_RANGETYPE :
                    601:                kdlog_beg = (kdr->value1);
                    602:                kdlog_end = (kdr->value2);
                    603:                kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    604:                kdebug_flags |= (KDBG_RANGECHECK | KDBG_RANGETYPE);
                    605:                break;
                    606:        case KDBG_TYPENONE :
                    607:                kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
                    608:                kdlog_beg = 0;
                    609:                kdlog_end = 0;
                    610:                break;
                    611:        default :
                    612:                ret = EINVAL;
                    613:                break;
                    614:        }
                    615: #endif /* 0 */
                    616:        return(EINVAL);
                    617: }
                    618: 
                    619: 
                    620: 
                    621: kdbg_readmap(kd_threadmap *buffer, size_t *number)
                    622: {
                    623:   int avail = *number;
                    624:   int ret = 0;
                    625:   int count = 0;
                    626: 
                    627:   count = avail/sizeof (kd_threadmap);
                    628: 
                    629:   if (count && (count <= kd_mapcount))
                    630:     {
                    631:       if((kdebug_flags & KDBG_MAPINIT) && kd_mapsize && kd_mapptr)
                    632:        {
                    633:          if (*number < kd_mapsize)
                    634:            ret=EINVAL;
                    635:          else
                    636:            {
                    637:              if (copyout(kd_mapptr, buffer, kd_mapsize))
                    638:                ret=EINVAL;
                    639:            }
                    640:        }
                    641:       else
                    642:        ret=EINVAL;
                    643:     }
                    644:   else
                    645:     ret=EINVAL;
                    646: 
                    647:   if ((kdebug_flags & KDBG_MAPINIT) && kd_mapsize && kd_mapptr)
                    648:     {
                    649:       kmem_free(kernel_map, (char *)kd_mapptr, kd_mapsize);
                    650:       kdebug_flags &= ~KDBG_MAPINIT;
                    651:       kd_mapsize = 0;
                    652:       kd_mapptr = (kd_threadmap *) 0;
                    653:       kd_mapcount = 0;
                    654:     }  
                    655: 
                    656:   return(ret);
                    657: }
                    658: 
                    659: 
                    660: kdbg_control(name, namelen, where, sizep)
                    661: int *name;
                    662: u_int namelen;
                    663: char *where;
                    664: size_t *sizep;
                    665: {
                    666: int ret=0;
                    667: int size=*sizep;
                    668: int max_entries;
                    669: unsigned int value = name[1];
                    670: kd_regtype kd_Reg;
                    671: kbufinfo_t kd_bufinfo;
                    672: 
                    673: pid_t curpid;
                    674: struct proc *p, *curproc;
                    675: 
                    676:         if(curproc = current_proc())
                    677:          curpid = curproc->p_pid;
                    678:        else
                    679:          return (ESRCH);
                    680: 
                    681:         if (global_state_pid == -1)
                    682:            global_state_pid = curpid;
                    683:        else if (global_state_pid != curpid)
                    684:          {
                    685:            if((p = pfind(global_state_pid)) == NULL)
                    686:              {
                    687:                /* The global pid no longer exists */
                    688:                global_state_pid = curpid;
                    689:              }
                    690:            else
                    691:              {
                    692:                /* The global pid exists, deny this request */
                    693:                return(EBUSY);
                    694:              }
                    695:          }
                    696: 
                    697:        switch(name[0]) {
                    698:                case KERN_KDEFLAGS:
                    699:                        value &= KDBG_USERFLAGS;
                    700:                        kdebug_flags |= value;
                    701:                        break;
                    702:                case KERN_KDDFLAGS:
                    703:                        value &= KDBG_USERFLAGS;
                    704:                        kdebug_flags &= ~value;
                    705:                        break;
                    706:                case KERN_KDENABLE:    /* used to enable or disable */
                    707:                  if (value)
                    708:                    {
                    709:                      /* enable only if buffer is initialized */
                    710:                      if (!(kdebug_flags & KDBG_BUFINIT))
                    711:                        {
                    712:                          ret=EINVAL;
                    713:                          break;
                    714:                        }
                    715:                    }
                    716:                  kdebug_enable=(value)?1:0;
                    717:                  kdebug_nolog = (value)?0:1;
                    718:                  if (kdebug_enable)
                    719:                      kdbg_mapinit();
                    720:                  break;
                    721:                case KERN_KDSETBUF:
                    722:                  /* We allow a maximum buffer size of 25% of memory */
                    723:                  /* 'value' is the desired number of trace entries */
                    724:                        max_entries = (mem_size/4) / sizeof(kd_buf);
                    725:                        if (value <= max_entries)
                    726:                                nkdbufs = value;
                    727:                        else
                    728:                          nkdbufs = max_entries;
                    729:                        break;
                    730:                case KERN_KDGETBUF:
                    731:                        if(size < sizeof(kbufinfo_t)) {
                    732:                            ret=EINVAL;
                    733:                            break;
                    734:                        }
                    735:                        kd_bufinfo.nkdbufs = nkdbufs;
                    736:                        kd_bufinfo.nkdthreads = kd_mapsize / sizeof(kd_threadmap);
                    737:                        kd_bufinfo.nolog = kdebug_nolog;
                    738:                        kd_bufinfo.flags = kdebug_flags;
                    739:                        if(copyout (&kd_bufinfo, where, sizeof(kbufinfo_t))) {
                    740:                          ret=EINVAL;
                    741:                        }
                    742:                        break;
                    743:                case KERN_KDSETUP:
                    744:                        ret=kdbg_reinit();
                    745:                        break;
                    746:                case KERN_KDREMOVE:
                    747:                        kdbg_clear();
                    748:                        break;
                    749:                case KERN_KDSETREG:
                    750:                        if(size < sizeof(kd_regtype)) {
                    751:                                ret=EINVAL;
                    752:                                break;
                    753:                        }
                    754:                        if (copyin(where, &kd_Reg, sizeof(kd_regtype))) {
                    755:                                ret= EINVAL;
                    756:                                break;
                    757:                        }
                    758:                        ret = kdbg_setreg(&kd_Reg);
                    759:                        break;
                    760:                case KERN_KDGETREG:
                    761:                        if(size < sizeof(kd_regtype)) {
                    762:                                ret = EINVAL;
                    763:                                break;
                    764:                        }
                    765:                        ret = kdbg_getreg(&kd_Reg);
                    766:                        if (copyout(&kd_Reg, where, sizeof(kd_regtype))){
                    767:                                ret=EINVAL;
                    768:                        }
                    769:                        break;
                    770:                case KERN_KDREADTR:
                    771:                        ret = kdbg_read(where, sizep);
                    772:                        break;
                    773:                case KERN_KDPIDTR:
                    774:                        if (size < sizeof(kd_regtype)) {
                    775:                                ret = EINVAL;
                    776:                                break;
                    777:                        }
                    778:                        if (copyin(where, &kd_Reg, sizeof(kd_regtype))) {
                    779:                                ret= EINVAL;
                    780:                                break;
                    781:                        }
                    782:                        ret = kdbg_setpid(&kd_Reg);
                    783:                        break;
                    784:                case KERN_KDPIDEX:
                    785:                        if (size < sizeof(kd_regtype)) {
                    786:                                ret = EINVAL;
                    787:                                break;
                    788:                        }
                    789:                        if (copyin(where, &kd_Reg, sizeof(kd_regtype))) {
                    790:                                ret= EINVAL;
                    791:                                break;
                    792:                        }
                    793:                        ret = kdbg_setpidex(&kd_Reg);
                    794:                        break;
                    795:                case KERN_KDTHRMAP:
                    796:                        ret = kdbg_readmap((kd_threadmap *)where, sizep);
                    797:                        break;
                    798:                case KERN_KDSETRTCDEC:
                    799:                        if (size < sizeof(kd_regtype)) {
                    800:                                ret = EINVAL;
                    801:                                break;
                    802:                        }
                    803:                        if (copyin(where, &kd_Reg, sizeof(kd_regtype))) {
                    804:                                ret= EINVAL;
                    805:                                break;
                    806:                        }
                    807:                        ret = kdbg_setrtcdec(&kd_Reg);
                    808:                        break;
                    809:                       
                    810:                default:
                    811:                        ret= EINVAL;
                    812:        }
                    813:        return(ret);
                    814: }
                    815: 
                    816: kdbg_read(kd_buf * buffer, size_t *number)
                    817: {
                    818: int avail=*number;
                    819: int count=0;
                    820: int copycount=0;
                    821: int totalcount=0;
                    822: 
                    823:        count = avail/sizeof(kd_buf);
                    824:        if (count) {
                    825:                if ((kdebug_flags & KDBG_BUFINIT) && kd_bufsize && kd_buffer) {
                    826:                        if (count > nkdbufs)
                    827:                                count = nkdbufs;
                    828:                        if (!(kdebug_flags & KDBG_WRAPPED) && (kd_bufptr > kd_readlast))
                    829:                          {
                    830:                            copycount = kd_bufptr-kd_readlast;
                    831:                            if (copycount > count)
                    832:                              copycount = count;
                    833: 
                    834:                            if (copyout(kd_readlast, buffer, copycount * sizeof(kd_buf)))
                    835:                              {
                    836:                                *number = 0;
                    837:                                return(EINVAL);
                    838:                              }
                    839:                            kd_readlast += copycount;
                    840:                            *number = copycount;
                    841:                            return(0);
                    842:                          }
                    843:                        else if (!(kdebug_flags & KDBG_WRAPPED) && (kd_bufptr == kd_readlast))
                    844:                          {
                    845:                            *number = 0;
                    846:                            return(0);
                    847:                          }
                    848:                        else
                    849:                          {
                    850:                            if (kdebug_flags & KDBG_WRAPPED)
                    851:                              {
                    852:                                kd_readlast = kd_bufptr;
                    853:                                kdebug_flags &= ~KDBG_WRAPPED;
                    854:                              }
                    855: 
                    856:                            /* Note that by setting kd_readlast equal to kd_bufptr,
                    857:                               we now treat the kd_buffer read the same as if we weren't
                    858:                               wrapped and kd_bufptr was less than kd_readlast.
                    859:                            */
                    860: 
                    861:                            /* first copyout from readlast to end of kd_buffer */
                    862:                            copycount = kd_buflast - kd_readlast;
                    863:                            if (copycount > count)
                    864:                              copycount = count;
                    865:                            if (copyout(kd_readlast, buffer, copycount * sizeof(kd_buf)))
                    866:                              {
                    867:                                *number = 0;
                    868:                                return(EINVAL);
                    869:                              }
                    870:                            buffer += copycount;
                    871:                            count -= copycount;
                    872:                            totalcount = copycount;
                    873:                            kd_readlast += copycount;
                    874:                            if (kd_readlast == kd_buflast)
                    875:                              kd_readlast = kd_buffer;
                    876:                            if (count == 0)
                    877:                              {
                    878:                                *number = totalcount;
                    879:                                return(0);
                    880:                              }
                    881: 
                    882:                             /* second copyout from top of kd_buffer to bufptr */
                    883:                            copycount = kd_bufptr - kd_readlast;
                    884:                            if (copycount > count)
                    885:                              copycount = count;
                    886:                            if (copycount == 0)
                    887:                              {
                    888:                                *number = totalcount;
                    889:                                return(0);
                    890:                              }
                    891:                            if (copyout(kd_readlast, buffer, copycount * sizeof(kd_buf)))
                    892:                              {
                    893:                                return(EINVAL);
                    894:                              }
                    895:                            kd_readlast += copycount;
                    896:                            totalcount += copycount;
                    897:                            *number = totalcount;
                    898:                            return(0);
                    899:                          }
                    900:                } /* end if KDBG_BUFINIT */             
                    901:        } /* end if count */
                    902:        return (EINVAL);
                    903: }

unix.superglobalmegacorp.com

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