2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 #include <machine/spl.h>
29 #include <mach/clock_types.h>
30 #include <mach/mach_types.h>
31 #include <mach/mach_time.h>
32 #include <machine/machine_routines.h>
34 #include <sys/kdebug.h>
35 #include <sys/errno.h>
36 #include <sys/param.h>
39 #include <sys/sysctl.h>
41 #include <kern/thread.h>
42 #include <kern/task.h>
43 #include <vm/vm_kern.h>
46 /* trace enable status */
47 unsigned int kdebug_enable
= 0;
49 /* track timestamps for security server's entropy needs */
50 uint64_t * kd_entropy_buffer
= 0;
51 unsigned int kd_entropy_bufsize
= 0;
52 unsigned int kd_entropy_count
= 0;
53 unsigned int kd_entropy_indx
= 0;
54 unsigned int kd_entropy_buftomem
= 0;
56 /* kd_buf kd_buffer[kd_bufsize/sizeof(kd_buf)]; */
58 unsigned int kd_buftomem
=0;
62 unsigned int nkdbufs
= 8192;
63 unsigned int kd_bufsize
= 0;
64 unsigned int kdebug_flags
= 0;
65 unsigned int kdebug_nolog
=1;
66 unsigned int kdlog_beg
=0;
67 unsigned int kdlog_end
=0;
68 unsigned int kdlog_value1
=0;
69 unsigned int kdlog_value2
=0;
70 unsigned int kdlog_value3
=0;
71 unsigned int kdlog_value4
=0;
73 unsigned long long kd_prev_timebase
= 0LL;
74 decl_simple_lock_data(,kd_trace_lock
);
76 kd_threadmap
*kd_mapptr
= 0;
77 unsigned int kd_mapsize
= 0;
78 unsigned int kd_mapcount
= 0;
79 unsigned int kd_maptomem
= 0;
81 pid_t global_state_pid
= -1; /* Used to control exclusive use of kd_buffer */
83 #define DBG_FUNC_MASK 0xfffffffc
86 extern natural_t rtclock_decrementer_min
;
98 /* task to string structure */
101 task_t
*task
; /* from procs task */
102 pid_t pid
; /* from procs p_pid */
103 char task_comm
[20]; /* from procs p_comm */
106 typedef struct tts tts_t
;
110 kd_threadmap
*map
; /* pointer to the map buffer */
116 typedef struct krt krt_t
;
118 /* This is for the CHUD toolkit call */
119 typedef void (*kd_chudhook_fn
) (unsigned int debugid
, unsigned int arg1
,
120 unsigned int arg2
, unsigned int arg3
,
121 unsigned int arg4
, unsigned int arg5
);
123 kd_chudhook_fn kdebug_chudhook
= 0; /* pointer to CHUD toolkit function */
125 /* Support syscall SYS_kdebug_trace */
126 kdebug_trace(p
, uap
, retval
)
128 struct kdebug_args
*uap
;
134 kernel_debug(uap
->code
, uap
->arg1
, uap
->arg2
, uap
->arg3
, uap
->arg4
, 0);
140 kernel_debug(debugid
, arg1
, arg2
, arg3
, arg4
, arg5
)
141 unsigned int debugid
, arg1
, arg2
, arg3
, arg4
, arg5
;
144 struct proc
*curproc
;
146 unsigned long long now
;
147 mach_timespec_t
*tsp
;
149 if (kdebug_enable
& KDEBUG_ENABLE_CHUD
) {
151 kdebug_chudhook(debugid
, arg1
, arg2
, arg3
, arg4
, arg5
);
153 if (!((kdebug_enable
& KDEBUG_ENABLE_ENTROPY
) ||
154 (kdebug_enable
& KDEBUG_ENABLE_TRACE
)))
158 s
= ml_set_interrupts_enabled(FALSE
);
160 if (kdebug_enable
& KDEBUG_ENABLE_ENTROPY
)
162 if (kd_entropy_indx
< kd_entropy_count
)
164 kd_entropy_buffer
[ kd_entropy_indx
] = mach_absolute_time();
168 if (kd_entropy_indx
== kd_entropy_count
)
170 /* Disable entropy collection */
171 kdebug_enable
&= ~KDEBUG_ENABLE_ENTROPY
;
177 ml_set_interrupts_enabled(s
);
181 usimple_lock(&kd_trace_lock
);
182 if (kdebug_flags
& KDBG_PIDCHECK
)
184 /* If kdebug flag is not set for current proc, return */
185 curproc
= current_proc();
186 if ((curproc
&& !(curproc
->p_flag
& P_KDEBUG
)) &&
187 ((debugid
&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED
, 0) | DBG_FUNC_NONE
)))
189 usimple_unlock(&kd_trace_lock
);
190 ml_set_interrupts_enabled(s
);
194 else if (kdebug_flags
& KDBG_PIDEXCLUDE
)
196 /* If kdebug flag is set for current proc, return */
197 curproc
= current_proc();
198 if ((curproc
&& (curproc
->p_flag
& P_KDEBUG
)) &&
199 ((debugid
&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED
, 0) | DBG_FUNC_NONE
)))
201 usimple_unlock(&kd_trace_lock
);
202 ml_set_interrupts_enabled(s
);
207 if (kdebug_flags
& KDBG_RANGECHECK
)
209 if ((debugid
< kdlog_beg
) || (debugid
> kdlog_end
)
210 && (debugid
>> 24 != DBG_TRACE
))
212 usimple_unlock(&kd_trace_lock
);
213 ml_set_interrupts_enabled(s
);
217 else if (kdebug_flags
& KDBG_VALCHECK
)
219 if ((debugid
& DBG_FUNC_MASK
) != kdlog_value1
&&
220 (debugid
& DBG_FUNC_MASK
) != kdlog_value2
&&
221 (debugid
& DBG_FUNC_MASK
) != kdlog_value3
&&
222 (debugid
& DBG_FUNC_MASK
) != kdlog_value4
&&
223 (debugid
>> 24 != DBG_TRACE
))
225 usimple_unlock(&kd_trace_lock
);
226 ml_set_interrupts_enabled(s
);
231 kd
->debugid
= debugid
;
236 kd
->arg5
= (int)current_act();
238 kd
->arg5
|= KDBG_CPU_MASK
;
240 now
= kd
->timestamp
= mach_absolute_time();
242 /* Watch for out of order timestamps */
244 if (now
< kd_prev_timebase
)
246 kd
->timestamp
= ++kd_prev_timebase
;
250 /* Then just store the previous timestamp */
251 kd_prev_timebase
= now
;
257 if (kd_bufptr
>= kd_buflast
)
258 kd_bufptr
= kd_buffer
;
259 if (kd_bufptr
== kd_readlast
) {
260 if (kdebug_flags
& KDBG_NOWRAP
)
262 kdebug_flags
|= KDBG_WRAPPED
;
264 usimple_unlock(&kd_trace_lock
);
265 ml_set_interrupts_enabled(s
);
269 kernel_debug1(debugid
, arg1
, arg2
, arg3
, arg4
, arg5
)
270 unsigned int debugid
, arg1
, arg2
, arg3
, arg4
, arg5
;
273 struct proc
*curproc
;
275 unsigned long long now
;
276 mach_timespec_t
*tsp
;
278 if (kdebug_enable
& KDEBUG_ENABLE_CHUD
) {
280 (void)kdebug_chudhook(debugid
, arg1
, arg2
, arg3
, arg4
, arg5
);
282 if (!((kdebug_enable
& KDEBUG_ENABLE_ENTROPY
) ||
283 (kdebug_enable
& KDEBUG_ENABLE_TRACE
)))
287 s
= ml_set_interrupts_enabled(FALSE
);
291 ml_set_interrupts_enabled(s
);
295 usimple_lock(&kd_trace_lock
);
296 if (kdebug_flags
& KDBG_PIDCHECK
)
298 /* If kdebug flag is not set for current proc, return */
299 curproc
= current_proc();
300 if ((curproc
&& !(curproc
->p_flag
& P_KDEBUG
)) &&
301 ((debugid
&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED
, 0) | DBG_FUNC_NONE
)))
303 usimple_unlock(&kd_trace_lock
);
304 ml_set_interrupts_enabled(s
);
308 else if (kdebug_flags
& KDBG_PIDEXCLUDE
)
310 /* If kdebug flag is set for current proc, return */
311 curproc
= current_proc();
312 if ((curproc
&& (curproc
->p_flag
& P_KDEBUG
)) &&
313 ((debugid
&0xffff0000) != (MACHDBG_CODE(DBG_MACH_SCHED
, 0) | DBG_FUNC_NONE
)))
315 usimple_unlock(&kd_trace_lock
);
316 ml_set_interrupts_enabled(s
);
321 if (kdebug_flags
& KDBG_RANGECHECK
)
323 if ((debugid
< kdlog_beg
) || (debugid
> kdlog_end
)
324 && (debugid
>> 24 != DBG_TRACE
))
326 usimple_unlock(&kd_trace_lock
);
327 ml_set_interrupts_enabled(s
);
331 else if (kdebug_flags
& KDBG_VALCHECK
)
333 if ((debugid
& DBG_FUNC_MASK
) != kdlog_value1
&&
334 (debugid
& DBG_FUNC_MASK
) != kdlog_value2
&&
335 (debugid
& DBG_FUNC_MASK
) != kdlog_value3
&&
336 (debugid
& DBG_FUNC_MASK
) != kdlog_value4
&&
337 (debugid
>> 24 != DBG_TRACE
))
339 usimple_unlock(&kd_trace_lock
);
340 ml_set_interrupts_enabled(s
);
346 kd
->debugid
= debugid
;
352 now
= kd
->timestamp
= mach_absolute_time();
354 /* Watch for out of order timestamps */
356 if (now
< kd_prev_timebase
)
358 /* timestamps are out of order -- adjust */
359 kd
->timestamp
= ++kd_prev_timebase
;
363 /* Then just store the previous timestamp */
364 kd_prev_timebase
= now
;
369 if (kd_bufptr
>= kd_buflast
)
370 kd_bufptr
= kd_buffer
;
371 if (kd_bufptr
== kd_readlast
) {
372 if (kdebug_flags
& KDBG_NOWRAP
)
374 kdebug_flags
|= KDBG_WRAPPED
;
376 usimple_unlock(&kd_trace_lock
);
377 ml_set_interrupts_enabled(s
);
383 kd_bufsize
= nkdbufs
* sizeof(kd_buf
);
384 if (kmem_alloc(kernel_map
, &kd_buftomem
,
385 (vm_size_t
)kd_bufsize
) == KERN_SUCCESS
)
386 kd_buffer
= (kd_buf
*) kd_buftomem
;
387 else kd_buffer
= (kd_buf
*) 0;
388 kdebug_flags
&= ~KDBG_WRAPPED
;
390 simple_lock_init(&kd_trace_lock
);
391 kdebug_flags
|= (KDBG_INIT
| KDBG_BUFINIT
);
392 kd_bufptr
= kd_buffer
;
393 kd_buflast
= &kd_bufptr
[nkdbufs
];
394 kd_readlast
= kd_bufptr
;
395 kd_prev_timebase
= 0LL;
399 kdebug_flags
&= ~(KDBG_INIT
| KDBG_BUFINIT
);
410 /* Disable trace collecting */
411 kdebug_enable
&= ~KDEBUG_ENABLE_TRACE
;
414 if ((kdebug_flags
& KDBG_INIT
) && (kdebug_flags
& KDBG_BUFINIT
) && kd_bufsize
&& kd_buffer
)
415 kmem_free(kernel_map
, (vm_offset_t
)kd_buffer
, kd_bufsize
);
417 if ((kdebug_flags
& KDBG_MAPINIT
) && kd_mapsize
&& kd_mapptr
)
419 kmem_free(kernel_map
, (vm_offset_t
)kd_mapptr
, kd_mapsize
);
420 kdebug_flags
&= ~KDBG_MAPINIT
;
422 kd_mapptr
= (kd_threadmap
*) 0;
426 ret
= kdbg_bootstrap();
431 void kdbg_trace_data(struct proc
*proc
, long *arg_pid
)
436 *arg_pid
= proc
->p_pid
;
442 void kdbg_trace_string(struct proc
*proc
, long *arg1
, long *arg2
, long *arg3
, long *arg4
)
458 /* Collect the pathname for tracing */
459 dbg_nameptr
= proc
->p_comm
;
460 dbg_namelen
= strlen(proc
->p_comm
);
466 if(dbg_namelen
> sizeof(dbg_parms
))
467 dbg_namelen
= sizeof(dbg_parms
);
469 for(i
=0;dbg_namelen
> 0; i
++)
471 dbg_parms
[i
]=*(long*)dbg_nameptr
;
472 dbg_nameptr
+= sizeof(long);
473 dbg_namelen
-= sizeof(long);
482 kdbg_resolve_map(thread_act_t th_act
, krt_t
*t
)
484 kd_threadmap
*mapptr
;
486 if(t
->count
< t
->maxcount
)
488 mapptr
=&t
->map
[t
->count
];
489 mapptr
->thread
= (unsigned int)th_act
;
490 (void) strncpy (mapptr
->command
, t
->atts
->task_comm
,
491 sizeof(t
->atts
->task_comm
)-1);
492 mapptr
->command
[sizeof(t
->atts
->task_comm
)-1] = '\0';
495 Some kernel threads have no associated pid.
496 We still need to mark the entry as valid.
499 mapptr
->valid
= t
->atts
->pid
;
511 int tts_count
; /* number of task-to-string structures */
512 struct tts
*tts_mapptr
;
513 unsigned int tts_mapsize
= 0;
514 unsigned int tts_maptomem
=0;
518 if (kdebug_flags
& KDBG_MAPINIT
)
521 /* Calculate the sizes of map buffers*/
522 for (p
= allproc
.lh_first
, kd_mapcount
=0, tts_count
=0; p
;
523 p
= p
->p_list
.le_next
)
525 kd_mapcount
+= get_task_numacts((task_t
)p
->task
);
530 * The proc count could change during buffer allocation,
531 * so introduce a small fudge factor to bump up the
532 * buffer sizes. This gives new tasks some chance of
533 * making into the tables. Bump up by 10%.
535 kd_mapcount
+= kd_mapcount
/10;
536 tts_count
+= tts_count
/10;
538 kd_mapsize
= kd_mapcount
* sizeof(kd_threadmap
);
539 if((kmem_alloc(kernel_map
, & kd_maptomem
,
540 (vm_size_t
)kd_mapsize
) == KERN_SUCCESS
))
542 kd_mapptr
= (kd_threadmap
*) kd_maptomem
;
543 bzero(kd_mapptr
, kd_mapsize
);
546 kd_mapptr
= (kd_threadmap
*) 0;
548 tts_mapsize
= tts_count
* sizeof(struct tts
);
549 if((kmem_alloc(kernel_map
, & tts_maptomem
,
550 (vm_size_t
)tts_mapsize
) == KERN_SUCCESS
))
552 tts_mapptr
= (struct tts
*) tts_maptomem
;
553 bzero(tts_mapptr
, tts_mapsize
);
556 tts_mapptr
= (struct tts
*) 0;
560 * We need to save the procs command string
561 * and take a reference for each task associated
562 * with a valid process
566 for (p
= allproc
.lh_first
, i
=0; p
&& i
< tts_count
;
567 p
= p
->p_list
.le_next
) {
568 if (p
->p_flag
& P_WEXIT
)
571 if (task_reference_try(p
->task
)) {
572 tts_mapptr
[i
].task
= p
->task
;
573 tts_mapptr
[i
].pid
= p
->p_pid
;
574 (void)strncpy(&tts_mapptr
[i
].task_comm
, p
->p_comm
, sizeof(tts_mapptr
[i
].task_comm
) - 1);
582 if (kd_mapptr
&& tts_mapptr
)
584 kdebug_flags
|= KDBG_MAPINIT
;
585 /* Initialize thread map data */
586 akrt
.map
= kd_mapptr
;
588 akrt
.maxcount
= kd_mapcount
;
590 for (i
=0; i
< tts_count
; i
++)
592 akrt
.atts
= &tts_mapptr
[i
];
593 task_act_iterate_wth_args(tts_mapptr
[i
].task
, kdbg_resolve_map
, &akrt
);
594 task_deallocate((task_t
) tts_mapptr
[i
].task
);
596 kmem_free(kernel_map
, (vm_offset_t
)tts_mapptr
, tts_mapsize
);
604 /* Clean up the trace buffer */
605 global_state_pid
= -1;
606 kdebug_enable
&= ~KDEBUG_ENABLE_TRACE
;
608 kdebug_flags
&= ~KDBG_BUFINIT
;
609 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
610 kdebug_flags
&= ~(KDBG_NOWRAP
| KDBG_RANGECHECK
| KDBG_VALCHECK
);
611 kdebug_flags
&= ~(KDBG_PIDCHECK
| KDBG_PIDEXCLUDE
);
612 kmem_free(kernel_map
, (vm_offset_t
)kd_buffer
, kd_bufsize
);
613 kd_buffer
= (kd_buf
*)0;
615 kd_prev_timebase
= 0LL;
617 /* Clean up the thread map buffer */
618 kdebug_flags
&= ~KDBG_MAPINIT
;
619 kmem_free(kernel_map
, (vm_offset_t
)kd_mapptr
, kd_mapsize
);
620 kd_mapptr
= (kd_threadmap
*) 0;
625 kdbg_setpid(kd_regtype
*kdr
)
631 pid
= (pid_t
)kdr
->value1
;
632 flag
= (int)kdr
->value2
;
636 if ((p
= pfind(pid
)) == NULL
)
640 if (flag
== 1) /* turn on pid check for this and all pids */
642 kdebug_flags
|= KDBG_PIDCHECK
;
643 kdebug_flags
&= ~KDBG_PIDEXCLUDE
;
644 p
->p_flag
|= P_KDEBUG
;
646 else /* turn off pid check for this pid value */
648 /* Don't turn off all pid checking though */
649 /* kdebug_flags &= ~KDBG_PIDCHECK;*/
650 p
->p_flag
&= ~P_KDEBUG
;
659 /* This is for pid exclusion in the trace buffer */
660 kdbg_setpidex(kd_regtype
*kdr
)
666 pid
= (pid_t
)kdr
->value1
;
667 flag
= (int)kdr
->value2
;
671 if ((p
= pfind(pid
)) == NULL
)
675 if (flag
== 1) /* turn on pid exclusion */
677 kdebug_flags
|= KDBG_PIDEXCLUDE
;
678 kdebug_flags
&= ~KDBG_PIDCHECK
;
679 p
->p_flag
|= P_KDEBUG
;
681 else /* turn off pid exclusion for this pid value */
683 /* Don't turn off all pid exclusion though */
684 /* kdebug_flags &= ~KDBG_PIDEXCLUDE;*/
685 p
->p_flag
&= ~P_KDEBUG
;
694 /* This is for setting a minimum decrementer value */
695 kdbg_setrtcdec(kd_regtype
*kdr
)
700 decval
= (natural_t
)kdr
->value1
;
702 if (decval
&& decval
< KDBG_MINRTCDEC
)
706 rtclock_decrementer_min
= decval
;
715 kdbg_setreg(kd_regtype
* kdr
)
718 unsigned int val_1
, val_2
, val
;
721 case KDBG_CLASSTYPE
:
722 val_1
= (kdr
->value1
& 0xff);
723 val_2
= (kdr
->value2
& 0xff);
724 kdlog_beg
= (val_1
<<24);
725 kdlog_end
= (val_2
<<24);
726 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
727 kdebug_flags
&= ~KDBG_VALCHECK
; /* Turn off specific value check */
728 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_CLASSTYPE
);
730 case KDBG_SUBCLSTYPE
:
731 val_1
= (kdr
->value1
& 0xff);
732 val_2
= (kdr
->value2
& 0xff);
734 kdlog_beg
= ((val_1
<<24) | (val_2
<< 16));
735 kdlog_end
= ((val_1
<<24) | (val
<< 16));
736 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
737 kdebug_flags
&= ~KDBG_VALCHECK
; /* Turn off specific value check */
738 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_SUBCLSTYPE
);
740 case KDBG_RANGETYPE
:
741 kdlog_beg
= (kdr
->value1
);
742 kdlog_end
= (kdr
->value2
);
743 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
744 kdebug_flags
&= ~KDBG_VALCHECK
; /* Turn off specific value check */
745 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_RANGETYPE
);
748 kdlog_value1
= (kdr
->value1
);
749 kdlog_value2
= (kdr
->value2
);
750 kdlog_value3
= (kdr
->value3
);
751 kdlog_value4
= (kdr
->value4
);
752 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
753 kdebug_flags
&= ~KDBG_RANGECHECK
; /* Turn off range check */
754 kdebug_flags
|= KDBG_VALCHECK
; /* Turn on specific value check */
757 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
768 kdbg_getreg(kd_regtype
* kdr
)
771 unsigned int val_1
, val_2
, val
;
774 case KDBG_CLASSTYPE
:
775 val_1
= (kdr
->value1
& 0xff);
777 kdlog_beg
= (val_1
<<24);
778 kdlog_end
= (val_2
<<24);
779 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
780 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_CLASSTYPE
);
782 case KDBG_SUBCLSTYPE
:
783 val_1
= (kdr
->value1
& 0xff);
784 val_2
= (kdr
->value2
& 0xff);
786 kdlog_beg
= ((val_1
<<24) | (val_2
<< 16));
787 kdlog_end
= ((val_1
<<24) | (val
<< 16));
788 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
789 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_SUBCLSTYPE
);
791 case KDBG_RANGETYPE
:
792 kdlog_beg
= (kdr
->value1
);
793 kdlog_end
= (kdr
->value2
);
794 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
795 kdebug_flags
|= (KDBG_RANGECHECK
| KDBG_RANGETYPE
);
798 kdebug_flags
&= (unsigned int)~KDBG_CKTYPES
;
812 kdbg_readmap(kd_threadmap
*buffer
, size_t *number
)
818 count
= avail
/sizeof (kd_threadmap
);
820 if (count
&& (count
<= kd_mapcount
))
822 if((kdebug_flags
& KDBG_MAPINIT
) && kd_mapsize
&& kd_mapptr
)
824 if (*number
< kd_mapsize
)
828 if (copyout(kd_mapptr
, buffer
, kd_mapsize
))
838 if ((kdebug_flags
& KDBG_MAPINIT
) && kd_mapsize
&& kd_mapptr
)
840 kmem_free(kernel_map
, (vm_offset_t
)kd_mapptr
, kd_mapsize
);
841 kdebug_flags
&= ~KDBG_MAPINIT
;
843 kd_mapptr
= (kd_threadmap
*) 0;
850 kdbg_getentropy (mach_timespec_t
* buffer
, size_t *number
, int ms_timeout
)
854 int count
= 0; /* The number of timestamp entries that will fill buffer */
856 if (kd_entropy_buffer
)
859 kd_entropy_count
= avail
/sizeof(mach_timespec_t
);
860 kd_entropy_bufsize
= kd_entropy_count
* sizeof(mach_timespec_t
);
863 /* Enforce maximum entropy entries here if needed */
865 /* allocate entropy buffer */
866 if (kmem_alloc(kernel_map
, &kd_entropy_buftomem
,
867 (vm_size_t
)kd_entropy_bufsize
) == KERN_SUCCESS
)
869 kd_entropy_buffer
= (uint64_t *) kd_entropy_buftomem
;
873 kd_entropy_buffer
= (uint64_t *) 0;
874 kd_entropy_count
= 0;
882 /* Enable entropy sampling */
883 kdebug_enable
|= KDEBUG_ENABLE_ENTROPY
;
885 ret
= tsleep (kdbg_getentropy
, PRIBIO
| PCATCH
, "kd_entropy", (ms_timeout
/(1000/HZ
)));
887 /* Disable entropy sampling */
888 kdebug_enable
&= ~KDEBUG_ENABLE_ENTROPY
;
893 if (kd_entropy_indx
> 0)
895 /* copyout the buffer */
896 if (copyout(kd_entropy_buffer
, buffer
, kd_entropy_indx
* sizeof(mach_timespec_t
)))
899 *number
= kd_entropy_indx
;
903 kd_entropy_count
= 0;
905 kd_entropy_buftomem
= 0;
906 kmem_free(kernel_map
, (vm_offset_t
)kd_entropy_buffer
, kd_entropy_bufsize
);
907 kd_entropy_buffer
= (uint64_t *) 0;
913 * This function is provided for the CHUD toolkit only.
915 * zero disables kdebug_chudhook function call
916 * non-zero enables kdebug_chudhook function call
918 * address of the enabled kdebug_chudhook function
921 void kdbg_control_chud(int val
, void *fn
)
924 /* enable chudhook */
925 kdebug_enable
|= KDEBUG_ENABLE_CHUD
;
926 kdebug_chudhook
= fn
;
929 /* disable chudhook */
930 kdebug_enable
&= ~KDEBUG_ENABLE_CHUD
;
936 kdbg_control(name
, namelen
, where
, sizep
)
945 unsigned int value
= name
[1];
947 kbufinfo_t kd_bufinfo
;
950 struct proc
*p
, *curproc
;
952 if (name
[0] == KERN_KDGETBUF
) {
954 Does not alter the global_state_pid
955 This is a passive request.
957 if (size
< sizeof(kd_bufinfo
.nkdbufs
)) {
959 There is not enough room to return even
960 the first element of the info structure.
965 kd_bufinfo
.nkdbufs
= nkdbufs
;
966 kd_bufinfo
.nkdthreads
= kd_mapsize
/ sizeof(kd_threadmap
);
967 kd_bufinfo
.nolog
= kdebug_nolog
;
968 kd_bufinfo
.flags
= kdebug_flags
;
969 kd_bufinfo
.bufid
= global_state_pid
;
971 if(size
>= sizeof(kbufinfo_t
)) {
972 /* Provide all the info we have */
973 if(copyout (&kd_bufinfo
, where
, sizeof(kbufinfo_t
)))
978 For backwards compatibility, only provide
979 as much info as there is room for.
981 if(copyout (&kd_bufinfo
, where
, size
))
986 else if (name
[0] == KERN_KDGETENTROPY
) {
987 if (kd_entropy_buffer
)
990 ret
= kdbg_getentropy((mach_timespec_t
*)where
, sizep
, value
);
994 if(curproc
= current_proc())
995 curpid
= curproc
->p_pid
;
999 if (global_state_pid
== -1)
1000 global_state_pid
= curpid
;
1001 else if (global_state_pid
!= curpid
)
1003 if((p
= pfind(global_state_pid
)) == NULL
)
1005 /* The global pid no longer exists */
1006 global_state_pid
= curpid
;
1010 /* The global pid exists, deny this request */
1017 value
&= KDBG_USERFLAGS
;
1018 kdebug_flags
|= value
;
1021 value
&= KDBG_USERFLAGS
;
1022 kdebug_flags
&= ~value
;
1024 case KERN_KDENABLE
: /* used to enable or disable */
1027 /* enable only if buffer is initialized */
1028 if (!(kdebug_flags
& KDBG_BUFINIT
))
1036 kdebug_enable
|= KDEBUG_ENABLE_TRACE
;
1038 kdebug_enable
&= ~KDEBUG_ENABLE_TRACE
;
1040 kdebug_nolog
= (value
)?0:1;
1042 if (kdebug_enable
& KDEBUG_ENABLE_TRACE
)
1046 /* We allow a maximum buffer size of 25% of either ram or max mapped address, whichever is smaller */
1047 /* 'value' is the desired number of trace entries */
1048 max_entries
= (sane_size
/4) / sizeof(kd_buf
);
1049 if (value
<= max_entries
)
1052 nkdbufs
= max_entries
;
1061 if(size
< sizeof(kd_regtype
)) {
1065 if (copyin(where
, &kd_Reg
, sizeof(kd_regtype
))) {
1069 ret
= kdbg_setreg(&kd_Reg
);
1072 if(size
< sizeof(kd_regtype
)) {
1076 ret
= kdbg_getreg(&kd_Reg
);
1077 if (copyout(&kd_Reg
, where
, sizeof(kd_regtype
))){
1082 ret
= kdbg_read(where
, sizep
);
1085 if (size
< sizeof(kd_regtype
)) {
1089 if (copyin(where
, &kd_Reg
, sizeof(kd_regtype
))) {
1093 ret
= kdbg_setpid(&kd_Reg
);
1096 if (size
< sizeof(kd_regtype
)) {
1100 if (copyin(where
, &kd_Reg
, sizeof(kd_regtype
))) {
1104 ret
= kdbg_setpidex(&kd_Reg
);
1107 ret
= kdbg_readmap((kd_threadmap
*)where
, sizep
);
1109 case KERN_KDSETRTCDEC
:
1110 if (size
< sizeof(kd_regtype
)) {
1114 if (copyin(where
, &kd_Reg
, sizeof(kd_regtype
))) {
1118 ret
= kdbg_setrtcdec(&kd_Reg
);
1127 kdbg_read(kd_buf
* buffer
, size_t *number
)
1134 unsigned int my_kdebug_flags
;
1135 kd_buf
* my_kd_bufptr
;
1137 s
= ml_set_interrupts_enabled(FALSE
);
1138 usimple_lock(&kd_trace_lock
);
1139 my_kdebug_flags
= kdebug_flags
;
1140 my_kd_bufptr
= kd_bufptr
;
1141 usimple_unlock(&kd_trace_lock
);
1142 ml_set_interrupts_enabled(s
);
1144 count
= avail
/sizeof(kd_buf
);
1146 if ((my_kdebug_flags
& KDBG_BUFINIT
) && kd_bufsize
&& kd_buffer
) {
1147 if (count
> nkdbufs
)
1149 if (!(my_kdebug_flags
& KDBG_WRAPPED
) && (my_kd_bufptr
> kd_readlast
))
1151 copycount
= my_kd_bufptr
-kd_readlast
;
1152 if (copycount
> count
)
1155 if (copyout(kd_readlast
, buffer
, copycount
* sizeof(kd_buf
)))
1160 kd_readlast
+= copycount
;
1161 *number
= copycount
;
1164 else if (!(my_kdebug_flags
& KDBG_WRAPPED
) && (my_kd_bufptr
== kd_readlast
))
1171 if (my_kdebug_flags
& KDBG_WRAPPED
)
1173 kd_readlast
= my_kd_bufptr
;
1174 kdebug_flags
&= ~KDBG_WRAPPED
;
1177 /* Note that by setting kd_readlast equal to my_kd_bufptr,
1178 we now treat the kd_buffer read the same as if we weren't
1179 wrapped and my_kd_bufptr was less than kd_readlast.
1182 /* first copyout from readlast to end of kd_buffer */
1183 copycount
= kd_buflast
- kd_readlast
;
1184 if (copycount
> count
)
1186 if (copyout(kd_readlast
, buffer
, copycount
* sizeof(kd_buf
)))
1191 buffer
+= copycount
;
1193 totalcount
= copycount
;
1194 kd_readlast
+= copycount
;
1195 if (kd_readlast
== kd_buflast
)
1196 kd_readlast
= kd_buffer
;
1199 *number
= totalcount
;
1203 /* second copyout from top of kd_buffer to bufptr */
1204 copycount
= my_kd_bufptr
- kd_readlast
;
1205 if (copycount
> count
)
1209 *number
= totalcount
;
1212 if (copyout(kd_readlast
, buffer
, copycount
* sizeof(kd_buf
)))
1216 kd_readlast
+= copycount
;
1217 totalcount
+= copycount
;
1218 *number
= totalcount
;
1221 } /* end if KDBG_BUFINIT */
1222 } /* end if count */
1226 unsigned char *getProcName(struct proc
*proc
);
1227 unsigned char *getProcName(struct proc
*proc
) {
1229 return (unsigned char *) &proc
->p_comm
; /* Return pointer to the proc name */