2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 #include <machine/spl.h>
26 #include <mach/clock_types.h>
27 #include <mach/mach_types.h>
28 #include <machine/machine_routines.h>
30 #include <sys/kdebug.h>
31 #include <sys/errno.h>
32 #include <sys/param.h>
35 #include <sys/sysctl.h>
37 #include <kern/thread.h>
38 #include <kern/task.h>
39 #include <vm/vm_kern.h>
42 /* trace enable status */
43 unsigned int kdebug_enable
= 0;
45 /* track timestamps for security server's entropy needs */
46 mach_timespec_t
* kd_entropy_buffer
= 0;
47 unsigned int kd_entropy_bufsize
= 0;
48 unsigned int kd_entropy_count
= 0;
49 unsigned int kd_entropy_indx
= 0;
50 unsigned int kd_entropy_buftomem
= 0;
52 /* kd_buf kd_buffer[kd_bufsize/sizeof(kd_buf)]; */
54 unsigned int kd_buftomem
=0;
58 unsigned int nkdbufs
= 8192;
59 unsigned int kd_bufsize
= 0;
60 unsigned int kdebug_flags
= 0;
61 unsigned int kdebug_nolog
=1;
62 unsigned int kdlog_beg
=0;
63 unsigned int kdlog_end
=0;
64 unsigned int kdlog_value1
=0;
65 unsigned int kdlog_value2
=0;
66 unsigned int kdlog_value3
=0;
67 unsigned int kdlog_value4
=0;
69 unsigned long long kd_prev_timebase
= 0LL;
70 decl_simple_lock_data(,kd_trace_lock
);
72 kd_threadmap
*kd_mapptr
= 0;
73 unsigned int kd_mapsize
= 0;
74 unsigned int kd_mapcount
= 0;
75 unsigned int kd_maptomem
= 0;
77 pid_t global_state_pid
= -1; /* Used to control exclusive use of kd_buffer */
79 #define DBG_FUNC_MASK 0xfffffffc
82 extern natural_t rtclock_decrementer_min
;
94 /* task to string structure */
98 char task_comm
[20]; /* from procs p_comm */
101 typedef struct tts tts_t
;
105 kd_threadmap
*map
; /* pointer to the map buffer */
111 typedef struct krt krt_t
;
113 /* This is for the CHUD toolkit call */
114 typedef void (*kd_chudhook_fn
) (unsigned int debugid
, unsigned int arg1
,
115 unsigned int arg2
, unsigned int arg3
,
116 unsigned int arg4
, unsigned int arg5
);
118 kd_chudhook_fn kdebug_chudhook
= 0; /* pointer to CHUD toolkit function */
120 /* Support syscall SYS_kdebug_trace */
121 kdebug_trace(p
, uap
, retval
)
123 struct kdebug_args
*uap
;
129 kernel_debug(uap
->code
, uap
->arg1
, uap
->arg2
, uap
->arg3
, uap
->arg4
, 0);
135 kernel_debug(debugid
, arg1
, arg2
, arg3
, arg4
, arg5
)
136 unsigned int debugid
, arg1
, arg2
, arg3
, arg4
, arg5
;
139 struct proc
*curproc
;
141 unsigned long long now
;
142 mach_timespec_t
*tsp
;
144 if (kdebug_enable
& KDEBUG_ENABLE_CHUD
) {
146 kdebug_chudhook(debugid
, arg1
, arg2
, arg3
, arg4
, arg5
);
148 if (!((kdebug_enable
& KDEBUG_ENABLE_ENTROPY
) ||
149 (kdebug_enable
& KDEBUG_ENABLE_TRACE
)))
153 s
= ml_set_interrupts_enabled(FALSE
);
155 if (kdebug_enable
& KDEBUG_ENABLE_ENTROPY
)
157 if (kd_entropy_indx
< kd_entropy_count
)
159 ml_get_timebase((unsigned long long *) &kd_entropy_buffer
[ kd_entropy_indx
]);
163 if (kd_entropy_indx
== kd_entropy_count
)
165 /* Disable entropy collection */
166 kdebug_enable
&= ~KDEBUG_ENABLE_ENTROPY
;
172 ml_set_interrupts_enabled(s
);
176 usimple_lock(&kd_trace_lock
);
177 if (kdebug_flags
& KDBG_PIDCHECK
)
179 /* If kdebug flag is not set for current proc, return */
180 curproc
= current_proc();
181 if ((curproc
&& !(curproc
->p_flag
& P_KDEBUG
)) &&
182 ((debugid
&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED
, 0) | DBG_FUNC_NONE
)))
184 usimple_unlock(&kd_trace_lock
);
185 ml_set_interrupts_enabled(s
);
189 else if (kdebug_flags
& KDBG_PIDEXCLUDE
)
191 /* If kdebug flag is set for current proc, return */
192 curproc
= current_proc();
193 if ((curproc
&& (curproc
->p_flag
& P_KDEBUG
)) &&
194 ((debugid
&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED
, 0) | DBG_FUNC_NONE
)))
196 usimple_unlock(&kd_trace_lock
);
197 ml_set_interrupts_enabled(s
);
202 if (kdebug_flags
& KDBG_RANGECHECK
)
204 if ((debugid
< kdlog_beg
) || (debugid
> kdlog_end
)
205 && (debugid
>> 24 != DBG_TRACE
))
207 usimple_unlock(&kd_trace_lock
);
208 ml_set_interrupts_enabled(s
);
212 else if (kdebug_flags
& KDBG_VALCHECK
)
214 if ((debugid
& DBG_FUNC_MASK
) != kdlog_value1
&&
215 (debugid
& DBG_FUNC_MASK
) != kdlog_value2
&&
216 (debugid
& DBG_FUNC_MASK
) != kdlog_value3
&&
217 (debugid
& DBG_FUNC_MASK
) != kdlog_value4
&&
218 (debugid
>> 24 != DBG_TRACE
))
220 usimple_unlock(&kd_trace_lock
);
221 ml_set_interrupts_enabled(s
);
226 kd
->debugid
= debugid
;
231 kd
->arg5
= (int)current_thread();
233 kd
->arg5
|= KDBG_CPU_MASK
;
235 ml_get_timebase((unsigned long long *)&kd
->timestamp
);
237 /* Watch for out of order timestamps */
238 now
= (((unsigned long long)kd
->timestamp
.tv_sec
) << 32) |
239 (unsigned long long)((unsigned int)(kd
->timestamp
.tv_nsec
));
241 if (now
< kd_prev_timebase
)
243 /* timestamps are out of order -- adjust */
245 tsp
= (mach_timespec_t
*)&kd_prev_timebase
;
246 kd
->timestamp
.tv_sec
= tsp
->tv_sec
;
247 kd
->timestamp
.tv_nsec
= tsp
->tv_nsec
;
251 /* Then just store the previous timestamp */
252 kd_prev_timebase
= now
;
258 if (kd_bufptr
>= kd_buflast
)
259 kd_bufptr
= kd_buffer
;
260 if (kd_bufptr
== kd_readlast
) {
261 if (kdebug_flags
& KDBG_NOWRAP
)
263 kdebug_flags
|= KDBG_WRAPPED
;
265 usimple_unlock(&kd_trace_lock
);
266 ml_set_interrupts_enabled(s
);
270 kernel_debug1(debugid
, arg1
, arg2
, arg3
, arg4
, arg5
)
271 unsigned int debugid
, arg1
, arg2
, arg3
, arg4
, arg5
;
274 struct proc
*curproc
;
276 unsigned long long now
;
277 mach_timespec_t
*tsp
;
279 if (kdebug_enable
& KDEBUG_ENABLE_CHUD
) {
281 (void)kdebug_chudhook(debugid
, arg1
, arg2
, arg3
, arg4
, arg5
);
283 if (!((kdebug_enable
& KDEBUG_ENABLE_ENTROPY
) ||
284 (kdebug_enable
& KDEBUG_ENABLE_TRACE
)))
288 s
= ml_set_interrupts_enabled(FALSE
);
292 ml_set_interrupts_enabled(s
);
296 usimple_lock(&kd_trace_lock
);
297 if (kdebug_flags
& KDBG_PIDCHECK
)
299 /* If kdebug flag is not set for current proc, return */
300 curproc
= current_proc();
301 if ((curproc
&& !(curproc
->p_flag
& P_KDEBUG
)) &&
302 ((debugid
&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED
, 0) | DBG_FUNC_NONE
)))
304 usimple_unlock(&kd_trace_lock
);
305 ml_set_interrupts_enabled(s
);
309 else if (kdebug_flags
& KDBG_PIDEXCLUDE
)
311 /* If kdebug flag is set for current proc, return */
312 curproc
= current_proc();
313 if ((curproc
&& (curproc
->p_flag
& P_KDEBUG
)) &&
314 ((debugid
&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED
, 0) | DBG_FUNC_NONE
)))
316 usimple_unlock(&kd_trace_lock
);
317 ml_set_interrupts_enabled(s
);
322 if (kdebug_flags
& KDBG_RANGECHECK
)
324 if ((debugid
< kdlog_beg
) || (debugid
> kdlog_end
)
325 && (debugid
>> 24 != DBG_TRACE
))
327 usimple_unlock(&kd_trace_lock
);
328 ml_set_interrupts_enabled(s
);
332 else if (kdebug_flags
& KDBG_VALCHECK
)
334 if ((debugid
& DBG_FUNC_MASK
) != kdlog_value1
&&
335 (debugid
& DBG_FUNC_MASK
) != kdlog_value2
&&
336 (debugid
& DBG_FUNC_MASK
) != kdlog_value3
&&
337 (debugid
& DBG_FUNC_MASK
) != kdlog_value4
&&
338 (debugid
>> 24 != DBG_TRACE
))
340 usimple_unlock(&kd_trace_lock
);
341 ml_set_interrupts_enabled(s
);
347 kd
->debugid
= debugid
;
353 ml_get_timebase((unsigned long long *)&kd
->timestamp
);
355 /* Watch for out of order timestamps */
356 now
= (((unsigned long long)kd
->timestamp
.tv_sec
) << 32) |
357 (unsigned long long)((unsigned int)(kd
->timestamp
.tv_nsec
));
359 if (now
< kd_prev_timebase
)
361 /* timestamps are out of order -- adjust */
363 tsp
= (mach_timespec_t
*)&kd_prev_timebase
;
364 kd
->timestamp
.tv_sec
= tsp
->tv_sec
;
365 kd
->timestamp
.tv_nsec
= tsp
->tv_nsec
;
369 /* Then just store the previous timestamp */
370 kd_prev_timebase
= now
;
375 if (kd_bufptr
>= kd_buflast
)
376 kd_bufptr
= kd_buffer
;
377 if (kd_bufptr
== kd_readlast
) {
378 if (kdebug_flags
& KDBG_NOWRAP
)
380 kdebug_flags
|= KDBG_WRAPPED
;
382 usimple_unlock(&kd_trace_lock
);
383 ml_set_interrupts_enabled(s
);
389 kd_bufsize
= nkdbufs
* sizeof(kd_buf
);
390 if (kmem_alloc(kernel_map
, &kd_buftomem
,
391 (vm_size_t
)kd_bufsize
) == KERN_SUCCESS
)
392 kd_buffer
= (kd_buf
*) kd_buftomem
;
393 else kd_buffer
= (kd_buf
*) 0;
394 kdebug_flags
&= ~KDBG_WRAPPED
;
396 simple_lock_init(&kd_trace_lock
);
397 kdebug_flags
|= (KDBG_INIT
| KDBG_BUFINIT
);
398 kd_bufptr
= kd_buffer
;
399 kd_buflast
= &kd_bufptr
[nkdbufs
];
400 kd_readlast
= kd_bufptr
;
401 kd_prev_timebase
= 0LL;
405 kdebug_flags
&= ~(KDBG_INIT
| KDBG_BUFINIT
);
416 /* Disable trace collecting */
417 kdebug_enable
&= ~KDEBUG_ENABLE_TRACE
;
420 if ((kdebug_flags
& KDBG_INIT
) && (kdebug_flags
& KDBG_BUFINIT
) && kd_bufsize
&& kd_buffer
)
421 kmem_free(kernel_map
, (char *)kd_buffer
, kd_bufsize
);
423 if ((kdebug_flags
& KDBG_MAPINIT
) && kd_mapsize
&& kd_mapptr
)
425 kmem_free(kernel_map
, (char *)kd_mapptr
, kd_mapsize
);
426 kdebug_flags
&= ~KDBG_MAPINIT
;
428 kd_mapptr
= (kd_threadmap
*) 0;
432 ret
= kdbg_bootstrap();
437 void kdbg_trace_string(struct proc
*proc
, long *arg1
, long *arg2
, long *arg3
, long *arg4
)
453 /* Collect the pathname for tracing */
454 dbg_nameptr
= proc
->p_comm
;
455 dbg_namelen
= strlen(proc
->p_comm
);
461 if(dbg_namelen
> sizeof(dbg_parms
))
462 dbg_namelen
= sizeof(dbg_parms
);
464 for(i
=0;dbg_namelen
> 0; i
++)
466 dbg_parms
[i
]=*(long*)dbg_nameptr
;
467 dbg_nameptr
+= sizeof(long);
468 dbg_namelen
-= sizeof(long);
477 kdbg_resolve_map(thread_act_t th_act
, krt_t
*t
)
479 kd_threadmap
*mapptr
;
481 if(t
->count
< t
->maxcount
)
483 mapptr
=&t
->map
[t
->count
];
484 mapptr
->thread
= (unsigned int)getshuttle_thread(th_act
);
486 (void) strncpy (mapptr
->command
, t
->atts
->task_comm
,
487 sizeof(t
->atts
->task_comm
)-1);
488 mapptr
->command
[sizeof(t
->atts
->task_comm
)-1] = '\0';
497 int tts_count
; /* number of task-to-string structures */
498 struct tts
*tts_mapptr
;
499 unsigned int tts_mapsize
= 0;
500 unsigned int tts_maptomem
=0;
504 if (kdebug_flags
& KDBG_MAPINIT
)
507 /* Calculate the sizes of map buffers*/
508 for (p
= allproc
.lh_first
, kd_mapcount
=0, tts_count
=0; p
;
509 p
= p
->p_list
.le_next
)
511 kd_mapcount
+= get_task_numacts((task_t
)p
->task
);
516 * The proc count could change during buffer allocation,
517 * so introduce a small fudge factor to bump up the
518 * buffer sizes. This gives new tasks some chance of
519 * making into the tables. Bump up by 10%.
521 kd_mapcount
+= kd_mapcount
/10;
522 tts_count
+= tts_count
/10;
524 kd_mapsize
= kd_mapcount
* sizeof(kd_threadmap
);
525 if((kmem_alloc(kernel_map
, & kd_maptomem
,
526 (vm_size_t
)kd_mapsize
) == KERN_SUCCESS
))
527 kd_mapptr
= (kd_threadmap
*) kd_maptomem
;
529 kd_mapptr
= (kd_threadmap
*) 0;
531 tts_mapsize
= tts_count
* sizeof(struct tts
);
532 if((kmem_alloc(kernel_map
, & tts_maptomem
,
533 (vm_size_t
)tts_mapsize
) == KERN_SUCCESS
))
534 tts_mapptr
= (struct tts
*) tts_maptomem
;
536 tts_mapptr
= (struct tts
*) 0;
540 * We need to save the procs command string
541 * and take a reference for each task associated
542 * with a valid process
546 for (p
= allproc
.lh_first
, i
=0; p
&& i
< tts_count
;
547 p
= p
->p_list
.le_next
) {
548 if (p
->p_flag
& P_WEXIT
)
551 if (task_reference_try(p
->task
)) {
552 tts_mapptr
[i
].task
= p
->task
;
553 (void)strncpy(&tts_mapptr
[i
].task_comm
, p
->p_comm
, sizeof(tts_mapptr
[i
].task_comm
) - 1);
561 if (kd_mapptr
&& tts_mapptr
)
563 kdebug_flags
|= KDBG_MAPINIT
;
564 /* Initialize thread map data */
565 akrt
.map
= kd_mapptr
;
567 akrt
.maxcount
= kd_mapcount
;
569 for (i
=0; i
< tts_count
; i
++)
571 akrt
.atts
= &tts_mapptr
[i
];
572 task_act_iterate_wth_args(tts_mapptr
[i
].task
, kdbg_resolve_map
, &akrt
);
573 task_deallocate(tts_mapptr
[i
].task
);
575 kmem_free(kernel_map
, (char *)tts_mapptr
, tts_mapsize
);
583 /* Clean up the trace buffer */
584 global_state_pid
= -1;
585 kdebug_enable
&= ~KDEBUG_ENABLE_TRACE
;
587 kdebug_flags
&= ~KDBG_BUFINIT
;
588 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
589 kdebug_flags
&= ~(KDBG_NOWRAP
| KDBG_RANGECHECK
| KDBG_VALCHECK
);
590 kdebug_flags
&= ~(KDBG_PIDCHECK
| KDBG_PIDEXCLUDE
);
591 kmem_free(kernel_map
, (char *)kd_buffer
, kd_bufsize
);
592 kd_buffer
= (kd_buf
*)0;
594 kd_prev_timebase
= 0LL;
596 /* Clean up the thread map buffer */
597 kdebug_flags
&= ~KDBG_MAPINIT
;
598 kmem_free(kernel_map
, (char *)kd_mapptr
, kd_mapsize
);
599 kd_mapptr
= (kd_threadmap
*) 0;
604 kdbg_setpid(kd_regtype
*kdr
)
610 pid
= (pid_t
)kdr
->value1
;
611 flag
= (int)kdr
->value2
;
615 if ((p
= pfind(pid
)) == NULL
)
619 if (flag
== 1) /* turn on pid check for this and all pids */
621 kdebug_flags
|= KDBG_PIDCHECK
;
622 kdebug_flags
&= ~KDBG_PIDEXCLUDE
;
623 p
->p_flag
|= P_KDEBUG
;
625 else /* turn off pid check for this pid value */
627 /* Don't turn off all pid checking though */
628 /* kdebug_flags &= ~KDBG_PIDCHECK;*/
629 p
->p_flag
&= ~P_KDEBUG
;
638 /* This is for pid exclusion in the trace buffer */
639 kdbg_setpidex(kd_regtype
*kdr
)
645 pid
= (pid_t
)kdr
->value1
;
646 flag
= (int)kdr
->value2
;
650 if ((p
= pfind(pid
)) == NULL
)
654 if (flag
== 1) /* turn on pid exclusion */
656 kdebug_flags
|= KDBG_PIDEXCLUDE
;
657 kdebug_flags
&= ~KDBG_PIDCHECK
;
658 p
->p_flag
|= P_KDEBUG
;
660 else /* turn off pid exclusion for this pid value */
662 /* Don't turn off all pid exclusion though */
663 /* kdebug_flags &= ~KDBG_PIDEXCLUDE;*/
664 p
->p_flag
&= ~P_KDEBUG
;
673 /* This is for setting a minimum decrementer value */
674 kdbg_setrtcdec(kd_regtype
*kdr
)
679 decval
= (natural_t
)kdr
->value1
;
681 if (decval
&& decval
< KDBG_MINRTCDEC
)
685 rtclock_decrementer_min
= decval
;
694 kdbg_setreg(kd_regtype
* kdr
)
697 unsigned int val_1
, val_2
, val
;
700 case KDBG_CLASSTYPE
:
701 val_1
= (kdr
->value1
& 0xff);
702 val_2
= (kdr
->value2
& 0xff);
703 kdlog_beg
= (val_1
<<24);
704 kdlog_end
= (val_2
<<24);
705 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
706 kdebug_flags
&= ~KDBG_VALCHECK
; /* Turn off specific value check */
707 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_CLASSTYPE
);
709 case KDBG_SUBCLSTYPE
:
710 val_1
= (kdr
->value1
& 0xff);
711 val_2
= (kdr
->value2
& 0xff);
713 kdlog_beg
= ((val_1
<<24) | (val_2
<< 16));
714 kdlog_end
= ((val_1
<<24) | (val
<< 16));
715 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
716 kdebug_flags
&= ~KDBG_VALCHECK
; /* Turn off specific value check */
717 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_SUBCLSTYPE
);
719 case KDBG_RANGETYPE
:
720 kdlog_beg
= (kdr
->value1
);
721 kdlog_end
= (kdr
->value2
);
722 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
723 kdebug_flags
&= ~KDBG_VALCHECK
; /* Turn off specific value check */
724 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_RANGETYPE
);
727 kdlog_value1
= (kdr
->value1
);
728 kdlog_value2
= (kdr
->value2
);
729 kdlog_value3
= (kdr
->value3
);
730 kdlog_value4
= (kdr
->value4
);
731 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
732 kdebug_flags
&= ~KDBG_RANGECHECK
; /* Turn off range check */
733 kdebug_flags
|= KDBG_VALCHECK
; /* Turn on specific value check */
736 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
747 kdbg_getreg(kd_regtype
* kdr
)
750 unsigned int val_1
, val_2
, val
;
753 case KDBG_CLASSTYPE
:
754 val_1
= (kdr
->value1
& 0xff);
756 kdlog_beg
= (val_1
<<24);
757 kdlog_end
= (val_2
<<24);
758 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
759 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_CLASSTYPE
);
761 case KDBG_SUBCLSTYPE
:
762 val_1
= (kdr
->value1
& 0xff);
763 val_2
= (kdr
->value2
& 0xff);
765 kdlog_beg
= ((val_1
<<24) | (val_2
<< 16));
766 kdlog_end
= ((val_1
<<24) | (val
<< 16));
767 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
768 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_SUBCLSTYPE
);
770 case KDBG_RANGETYPE
:
771 kdlog_beg
= (kdr
->value1
);
772 kdlog_end
= (kdr
->value2
);
773 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
774 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_RANGETYPE
);
777 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
791 kdbg_readmap(kd_threadmap
*buffer
, size_t *number
)
797 count
= avail
/sizeof (kd_threadmap
);
799 if (count
&& (count
<= kd_mapcount
))
801 if((kdebug_flags
& KDBG_MAPINIT
) && kd_mapsize
&& kd_mapptr
)
803 if (*number
< kd_mapsize
)
807 if (copyout(kd_mapptr
, buffer
, kd_mapsize
))
817 if ((kdebug_flags
& KDBG_MAPINIT
) && kd_mapsize
&& kd_mapptr
)
819 kmem_free(kernel_map
, (char *)kd_mapptr
, kd_mapsize
);
820 kdebug_flags
&= ~KDBG_MAPINIT
;
822 kd_mapptr
= (kd_threadmap
*) 0;
829 kdbg_getentropy (mach_timespec_t
* buffer
, size_t *number
, int ms_timeout
)
833 int count
= 0; /* The number of timestamp entries that will fill buffer */
835 if (kd_entropy_buffer
)
838 kd_entropy_count
= avail
/sizeof(mach_timespec_t
);
839 kd_entropy_bufsize
= kd_entropy_count
* sizeof(mach_timespec_t
);
842 /* Enforce maximum entropy entries here if needed */
844 /* allocate entropy buffer */
845 if (kmem_alloc(kernel_map
, &kd_entropy_buftomem
,
846 (vm_size_t
)kd_entropy_bufsize
) == KERN_SUCCESS
)
848 kd_entropy_buffer
= (mach_timespec_t
*)kd_entropy_buftomem
;
852 kd_entropy_buffer
= (mach_timespec_t
*) 0;
853 kd_entropy_count
= 0;
861 /* Enable entropy sampling */
862 kdebug_enable
|= KDEBUG_ENABLE_ENTROPY
;
864 ret
= tsleep (kdbg_getentropy
, PRIBIO
| PCATCH
, "kd_entropy", (ms_timeout
/(1000/HZ
)));
866 /* Disable entropy sampling */
867 kdebug_enable
&= ~KDEBUG_ENABLE_ENTROPY
;
872 if (kd_entropy_indx
> 0)
874 /* copyout the buffer */
875 if (copyout(kd_entropy_buffer
, buffer
, kd_entropy_indx
* sizeof(mach_timespec_t
)))
878 *number
= kd_entropy_indx
;
882 kd_entropy_count
= 0;
884 kd_entropy_buftomem
= 0;
885 kmem_free(kernel_map
, (char *)kd_entropy_buffer
, kd_entropy_bufsize
);
886 kd_entropy_buffer
= (mach_timespec_t
*) 0;
892 * This function is provided for the CHUD toolkit only.
894 * zero disables kdebug_chudhook function call
895 * non-zero enables kdebug_chudhook function call
897 * address of the enabled kdebug_chudhook function
900 void kdbg_control_chud(int val
, void *fn
)
903 /* enable chudhook */
904 kdebug_enable
|= KDEBUG_ENABLE_CHUD
;
905 kdebug_chudhook
= fn
;
908 /* disable chudhook */
909 kdebug_enable
&= ~KDEBUG_ENABLE_CHUD
;
915 kdbg_control(name
, namelen
, where
, sizep
)
924 unsigned int value
= name
[1];
926 kbufinfo_t kd_bufinfo
;
929 struct proc
*p
, *curproc
;
931 if (name
[0] == KERN_KDGETBUF
) {
933 Does not alter the global_state_pid
934 This is a passive request.
936 if (size
< sizeof(kd_bufinfo
.nkdbufs
)) {
938 There is not enough room to return even
939 the first element of the info structure.
944 kd_bufinfo
.nkdbufs
= nkdbufs
;
945 kd_bufinfo
.nkdthreads
= kd_mapsize
/ sizeof(kd_threadmap
);
946 kd_bufinfo
.nolog
= kdebug_nolog
;
947 kd_bufinfo
.flags
= kdebug_flags
;
948 kd_bufinfo
.bufid
= global_state_pid
;
950 if(size
>= sizeof(kbufinfo_t
)) {
951 /* Provide all the info we have */
952 if(copyout (&kd_bufinfo
, where
, sizeof(kbufinfo_t
)))
957 For backwards compatibility, only provide
958 as much info as there is room for.
960 if(copyout (&kd_bufinfo
, where
, size
))
965 else if (name
[0] == KERN_KDGETENTROPY
) {
966 if (kd_entropy_buffer
)
969 ret
= kdbg_getentropy((mach_timespec_t
*)where
, sizep
, value
);
973 if(curproc
= current_proc())
974 curpid
= curproc
->p_pid
;
978 if (global_state_pid
== -1)
979 global_state_pid
= curpid
;
980 else if (global_state_pid
!= curpid
)
982 if((p
= pfind(global_state_pid
)) == NULL
)
984 /* The global pid no longer exists */
985 global_state_pid
= curpid
;
989 /* The global pid exists, deny this request */
996 value
&= KDBG_USERFLAGS
;
997 kdebug_flags
|= value
;
1000 value
&= KDBG_USERFLAGS
;
1001 kdebug_flags
&= ~value
;
1003 case KERN_KDENABLE
: /* used to enable or disable */
1006 /* enable only if buffer is initialized */
1007 if (!(kdebug_flags
& KDBG_BUFINIT
))
1015 kdebug_enable
|= KDEBUG_ENABLE_TRACE
;
1017 kdebug_enable
&= ~KDEBUG_ENABLE_TRACE
;
1019 kdebug_nolog
= (value
)?0:1;
1021 if (kdebug_enable
& KDEBUG_ENABLE_TRACE
)
1025 /* We allow a maximum buffer size of 25% of memory */
1026 /* 'value' is the desired number of trace entries */
1027 max_entries
= (mem_size
/4) / sizeof(kd_buf
);
1028 if (value
<= max_entries
)
1031 nkdbufs
= max_entries
;
1040 if(size
< sizeof(kd_regtype
)) {
1044 if (copyin(where
, &kd_Reg
, sizeof(kd_regtype
))) {
1048 ret
= kdbg_setreg(&kd_Reg
);
1051 if(size
< sizeof(kd_regtype
)) {
1055 ret
= kdbg_getreg(&kd_Reg
);
1056 if (copyout(&kd_Reg
, where
, sizeof(kd_regtype
))){
1061 ret
= kdbg_read(where
, sizep
);
1064 if (size
< sizeof(kd_regtype
)) {
1068 if (copyin(where
, &kd_Reg
, sizeof(kd_regtype
))) {
1072 ret
= kdbg_setpid(&kd_Reg
);
1075 if (size
< sizeof(kd_regtype
)) {
1079 if (copyin(where
, &kd_Reg
, sizeof(kd_regtype
))) {
1083 ret
= kdbg_setpidex(&kd_Reg
);
1086 ret
= kdbg_readmap((kd_threadmap
*)where
, sizep
);
1088 case KERN_KDSETRTCDEC
:
1089 if (size
< sizeof(kd_regtype
)) {
1093 if (copyin(where
, &kd_Reg
, sizeof(kd_regtype
))) {
1097 ret
= kdbg_setrtcdec(&kd_Reg
);
1106 kdbg_read(kd_buf
* buffer
, size_t *number
)
1113 unsigned int my_kdebug_flags
;
1114 kd_buf
* my_kd_bufptr
;
1116 s
= ml_set_interrupts_enabled(FALSE
);
1117 usimple_lock(&kd_trace_lock
);
1118 my_kdebug_flags
= kdebug_flags
;
1119 my_kd_bufptr
= kd_bufptr
;
1120 usimple_unlock(&kd_trace_lock
);
1121 ml_set_interrupts_enabled(s
);
1123 count
= avail
/sizeof(kd_buf
);
1125 if ((my_kdebug_flags
& KDBG_BUFINIT
) && kd_bufsize
&& kd_buffer
) {
1126 if (count
> nkdbufs
)
1128 if (!(my_kdebug_flags
& KDBG_WRAPPED
) && (my_kd_bufptr
> kd_readlast
))
1130 copycount
= my_kd_bufptr
-kd_readlast
;
1131 if (copycount
> count
)
1134 if (copyout(kd_readlast
, buffer
, copycount
* sizeof(kd_buf
)))
1139 kd_readlast
+= copycount
;
1140 *number
= copycount
;
1143 else if (!(my_kdebug_flags
& KDBG_WRAPPED
) && (my_kd_bufptr
== kd_readlast
))
1150 if (my_kdebug_flags
& KDBG_WRAPPED
)
1152 kd_readlast
= my_kd_bufptr
;
1153 kdebug_flags
&= ~KDBG_WRAPPED
;
1156 /* Note that by setting kd_readlast equal to my_kd_bufptr,
1157 we now treat the kd_buffer read the same as if we weren't
1158 wrapped and my_kd_bufptr was less than kd_readlast.
1161 /* first copyout from readlast to end of kd_buffer */
1162 copycount
= kd_buflast
- kd_readlast
;
1163 if (copycount
> count
)
1165 if (copyout(kd_readlast
, buffer
, copycount
* sizeof(kd_buf
)))
1170 buffer
+= copycount
;
1172 totalcount
= copycount
;
1173 kd_readlast
+= copycount
;
1174 if (kd_readlast
== kd_buflast
)
1175 kd_readlast
= kd_buffer
;
1178 *number
= totalcount
;
1182 /* second copyout from top of kd_buffer to bufptr */
1183 copycount
= my_kd_bufptr
- kd_readlast
;
1184 if (copycount
> count
)
1188 *number
= totalcount
;
1191 if (copyout(kd_readlast
, buffer
, copycount
* sizeof(kd_buf
)))
1195 kd_readlast
+= copycount
;
1196 totalcount
+= copycount
;
1197 *number
= totalcount
;
1200 } /* end if KDBG_BUFINIT */
1201 } /* end if count */