Annotation of XNU/bsd/kern/kdebug.c, revision 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.