1#[cfg(target_os = "macos")]
4const DBG_APPS: u32 = 33;
5#[cfg(target_os = "macos")]
6const DBG_FUNC_START: u32 = 1;
7#[cfg(target_os = "macos")]
8const DBG_FUNC_END: u32 = 2;
9#[cfg(target_os = "macos")]
10const DBG_FUNC_NONE: u32 = 0;
11#[cfg(target_os = "macos")]
12const DBG_MACH_CHUD: u32 = 0x0a;
13#[cfg(target_os = "macos")]
14const KDBG_CLASS_OFFSET: u32 = 24;
15#[cfg(target_os = "macos")]
16const KDBG_SUBCLASS_OFFSET: u32 = 16;
17#[cfg(target_os = "macos")]
18const KDBG_CODE_OFFSET: u32 = 2;
19
20#[cfg(target_os = "macos")]
21fn appsdbg_code(subclass: u32, code: u32) -> u32 {
22 kdbg_code(DBG_APPS, subclass, code)
23}
24
25#[cfg(target_os = "macos")]
26fn kdbg_code(class: u32, subclass: u32, code: u32) -> u32 {
27 kdbg_eventid(class, subclass, code)
28}
29
30#[cfg(target_os = "macos")]
31fn kdbg_eventid(class: u32, subclass: u32, code: u32) -> u32 {
32 ((class & 0xff) << KDBG_CLASS_OFFSET) | ((subclass & 0xff) << KDBG_SUBCLASS_OFFSET) |
33 ((code & 0x3fff) << KDBG_CODE_OFFSET)
34}
35
36#[cfg(target_os = "macos")]
37pub fn start(code: u32, args: &[usize; 4]) {
38 unsafe {
39 kdebug_trace(appsdbg_code(DBG_MACH_CHUD, code) | DBG_FUNC_START,
40 args[0],
41 args[1],
42 args[2],
43 args[3],
44 0)
45 }
46}
47
48#[cfg(target_os = "macos")]
49pub fn end(code: u32, args: &[usize; 4]) {
50 unsafe {
51 kdebug_trace(appsdbg_code(DBG_MACH_CHUD, code) | DBG_FUNC_END,
52 args[0],
53 args[1],
54 args[2],
55 args[3],
56 0)
57 }
58}
59
60#[cfg(target_os = "macos")]
61pub fn trace(code: u32, args: &[usize; 4]) {
62 unsafe {
63 kdebug_trace(appsdbg_code(DBG_MACH_CHUD, code) | DBG_FUNC_NONE,
64 args[0],
65 args[1],
66 args[2],
67 args[3],
68 0)
69 }
70}
71
72#[cfg(not(target_os = "macos"))]
73pub fn start(code: u32, args: &[usize; 4]) {}
74#[cfg(not(target_os = "macos"))]
75pub fn end(code: u32, args: &[usize; 4]) {}
76#[cfg(not(target_os = "macos"))]
77pub fn trace(code: u32, args: &[usize; 4]) {}
78
79pub fn trace_function<R, F>(code: u32, args: &[usize; 4], func: F) -> R where F: FnOnce() -> R {
80 start(code, args);
81 let result = func();
82 end(code, args);
83 result
84}
85
86pub struct AutoTrace<'a> {
89 code: u32,
90 args: &'a [usize; 4],
91}
92
93impl<'a> AutoTrace<'a> {
94 pub fn new(code: u32, args: &'a [usize; 4]) -> AutoTrace<'a> {
95 start(code, args);
96 AutoTrace {
97 code: code,
98 args: args,
99 }
100 }
101}
102
103impl<'a> Drop for AutoTrace<'a> {
104 fn drop(&mut self) {
105 end(self.code, self.args);
106 }
107}
108
109#[cfg(target_os = "macos")]
110extern {
111 fn kdebug_trace(code: u32, arg0: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize);
112}