]> git.saurik.com Git - apple/xnu.git/blame - libsyscall/wrappers/kdebug_trace.c
xnu-3248.60.10.tar.gz
[apple/xnu.git] / libsyscall / wrappers / kdebug_trace.c
CommitLineData
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
30extern int __kdebug_trace64(uint32_t code, uint64_t arg1, uint64_t arg2,
31 uint64_t arg3, uint64_t arg4);
32extern 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. */
36static int
37kdebug_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
49static int
50kdebug_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
68int
69kdebug_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
86uint64_t
87kdebug_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}