]>
Commit | Line | Data |
---|---|---|
a1c7dba1 A |
1 | /* |
2 | * Copyright (c) 2014 Apple Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | #include <stdint.h> | |
3e170ce0 | 25 | #include <stdlib.h> |
a1c7dba1 A |
26 | #include <machine/cpu_capabilities.h> |
27 | #include <sys/kdebug.h> | |
28 | #include <sys/errno.h> | |
29 | ||
3e170ce0 A |
30 | extern int __kdebug_trace64(uint32_t code, uint64_t arg1, uint64_t arg2, |
31 | uint64_t arg3, uint64_t arg4); | |
32 | extern uint64_t __kdebug_trace_string(uint32_t debugid, uint64_t str_id, | |
33 | const char *str); | |
a1c7dba1 | 34 | |
3e170ce0 A |
35 | /* Returns non-zero if tracing is enabled. */ |
36 | static int | |
37 | kdebug_enabled(void) | |
38 | { | |
39 | volatile uint32_t *kdebug_enable_address = | |
40 | (volatile uint32_t *)(uintptr_t)(_COMM_PAGE_KDEBUG_ENABLE); | |
41 | ||
42 | if (*kdebug_enable_address == 0) { | |
43 | return 0; | |
44 | } | |
a1c7dba1 | 45 | |
3e170ce0 A |
46 | return 1; |
47 | } | |
a1c7dba1 | 48 | |
3e170ce0 A |
49 | static int |
50 | kdebug_validate_debugid(uint32_t debugid) | |
a1c7dba1 | 51 | { |
3e170ce0 | 52 | uint8_t debugid_class; |
a1c7dba1 A |
53 | |
54 | /* | |
3e170ce0 A |
55 | * This filtering is also done in the kernel, but we also do it here so |
56 | * that errors are returned in all cases, not just when the system call | |
57 | * is actually performed. | |
a1c7dba1 | 58 | */ |
3e170ce0 A |
59 | debugid_class = KDBG_EXTRACT_CLASS(debugid); |
60 | switch (debugid_class) { | |
a1c7dba1 | 61 | case DBG_TRACE: |
3e170ce0 | 62 | return EPERM; |
a1c7dba1 A |
63 | } |
64 | ||
3e170ce0 A |
65 | return 0; |
66 | } | |
67 | ||
68 | int | |
69 | kdebug_trace(uint32_t debugid, uint64_t arg1, uint64_t arg2, uint64_t arg3, | |
70 | uint64_t arg4) | |
71 | { | |
72 | int err; | |
73 | ||
74 | if (!kdebug_enabled()) { | |
a1c7dba1 A |
75 | return 0; |
76 | } | |
3e170ce0 A |
77 | |
78 | if ((err = kdebug_validate_debugid(debugid)) != 0) { | |
79 | errno = err; | |
80 | return -1; | |
81 | } | |
82 | ||
83 | return __kdebug_trace64(debugid, arg1, arg2, arg3, arg4); | |
84 | } | |
85 | ||
86 | uint64_t | |
87 | kdebug_trace_string(uint32_t debugid, uint64_t str_id, const char *str) | |
88 | { | |
89 | int err; | |
90 | ||
91 | if (!kdebug_enabled()) { | |
92 | return 0; | |
93 | } | |
94 | ||
95 | if ((int64_t)str_id == -1) { | |
96 | errno = EINVAL; | |
97 | return (uint64_t)-1; | |
98 | } | |
99 | ||
100 | if (str_id == 0 && str == NULL) { | |
101 | errno = EINVAL; | |
102 | return (uint64_t)-1; | |
103 | } | |
104 | ||
105 | if ((err = kdebug_validate_debugid(debugid)) != 0) { | |
106 | errno = err; | |
107 | return (uint64_t)-1; | |
108 | } | |
109 | ||
110 | return __kdebug_trace_string(debugid, str_id, str); | |
a1c7dba1 | 111 | } |