|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.