1/*
2 * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef BSD_SYS_KDEBUG_KERNEL_H
30#define BSD_SYS_KDEBUG_KERNEL_H
31
32#include <mach/boolean.h>
33#include <mach/clock_types.h>
34#include <stdbool.h>
35#include <stdint.h>
36#include <sys/cdefs.h>
37
38__BEGIN_DECLS
39
40#ifdef KERNEL
41
42/*
43 * To use kdebug in the kernel:
44 *
45 * #include <sys/kdebug_kernel.h>
46 *
47 * #define DBG_NETIPINIT NETDBG_CODE(DBG_NETIP, 1)
48 *
49 * void
50 * ip_init(void)
51 * {
52 * KDBG(DBG_NETIPINIT | DBG_FUNC_START, 1, 2, 3, 4);
53 * ...
54 * KDBG(DBG_NETIPINIT);
55 * ...
56 * KDBG(DBG_NETIPINIT | DBG_FUNC_END);
57 * }
58 */
59
60#pragma mark - kernel tracepoints
61
62/*
63 * The KDBG{,_DEBUG,_RELEASE,_FILTERED} macros are the preferred method of
64 * making tracepoints.
65 *
66 * Kernel pointers must be unslid or permuted using VM_KERNEL_UNSLIDE_OR_PERM.
67 * Do not trace any sensitive data.
68 */
69
70/*
71 * Traced on debug and development (and release macOS) kernels.
72 */
73#define KDBG(x, ...) KDBG_(, x, ## __VA_ARGS__, 4, 3, 2, 1, 0)
74
75/*
76 * Traced on debug and development (and release macOS) kernels if explicitly
77 * requested. Omitted from tracing without a typefilter.
78 */
79#define KDBG_FILTERED(x, ...) KDBG_(_FILTERED, x, ## __VA_ARGS__, 4, 3, 2, 1, 0)
80
81#ifdef KERNEL_PRIVATE
82
83/*
84 * Traced on debug and development (and release macOS) kernels, even if the
85 * process filter would reject it.
86 */
87#define KDBG_RELEASE_NOPROCFILT(x, ...) \
88 KDBG_(_RELEASE_NOPROCFILT, x, ## __VA_ARGS__, 4, 3, 2, 1, 0)
89
90#endif /* KERNEL_PRIVATE */
91
92/*
93 * Traced on debug, development, and release kernels.
94 *
95 * Only use this tracepoint if the events are required for a shipping trace
96 * tool.
97 */
98#define KDBG_RELEASE(x, ...) KDBG_(_RELEASE, x, ## __VA_ARGS__, 4, 3, 2, 1, 0)
99
100/*
101 * Traced only on debug kernels.
102 */
103#define KDBG_DEBUG(x, ...) KDBG_(_DEBUG, x, ## __VA_ARGS__, 4, 3, 2, 1, 0)
104
105#pragma mark - kernel API
106
107#ifdef KERNEL_PRIVATE
108
109/*
110 * kernel_debug_string provides the same functionality as the
111 * kdebug_trace_string syscall as a KPI. str_id is an in/out
112 * parameter that, if it's pointing to a string ID of 0, will
113 * receive a generated ID. If it provides a value in str_id,
114 * then that will be used, instead.
115 *
116 * Returns an errno indicating the type of failure.
117 */
118int kernel_debug_string(uint32_t debugid, uint64_t *str_id, const char *str);
119
120/*
121 * kernel_debug_disable disables event logging, but leaves any buffers
122 * intact.
123 */
124void kernel_debug_disable(void);
125
126#endif /* KERNEL_PRIVATE */
127
128/*
129 * Returns true if kdebug is using continuous time for its events, and false
130 * otherwise.
131 */
132bool kdebug_using_continuous_time(void);
133
134/*
135 * Convert an absolute time to a kdebug timestamp.
136 */
137extern uint64_t kdebug_timestamp_from_absolute(uint64_t abstime);
138
139/*
140 * Convert a continuous time to a kdebug timestamp.
141 */
142extern uint64_t kdebug_timestamp_from_continuous(uint64_t conttime);
143
144/*
145 * Capture a kdebug timestamp for the current time.
146 */
147extern uint64_t kdebug_timestamp(void);
148
149/*
150 * Returns true if kdebug will log an event with the provided debugid, and
151 * false otherwise.
152 */
153bool kdebug_debugid_enabled(uint32_t debugid);
154
155/*
156 * Returns true only if the debugid is explicitly enabled by filters. Returns
157 * false otherwise, including when no filters are active.
158 */
159bool kdebug_debugid_explicitly_enabled(uint32_t debugid);
160
161uint32_t kdebug_commpage_state(void);
162
163#pragma mark - Coprocessor/IOP tracing
164
165typedef enum {
166 /* Trace is now enabled. */
167 KD_CALLBACK_KDEBUG_ENABLED,
168 /*
169 * Trace is being disabled, but events are still accepted for the duration
170 * of the callback.
171 */
172 KD_CALLBACK_KDEBUG_DISABLED,
173 /*
174 * Request the latest events from the IOP and block until complete. Any
175 * events that occur prior to this callback being called may be dropped by
176 * the trace system.
177 */
178 KD_CALLBACK_SYNC_FLUSH,
179 /*
180 * The typefilter is being used.
181 *
182 * A read-only pointer to the typefilter is provided as the argument, valid
183 * only in the callback.
184 */
185 KD_CALLBACK_TYPEFILTER_CHANGED,
186 /*
187 * The coprocessor should emit data that snapshots the current state of the
188 * system.
189 */
190 KD_CALLBACK_SNAPSHOT_STATE,
191} kd_callback_type;
192
193__options_decl(kdebug_coproc_flags_t, uint32_t, {
194 /*
195 * Event timestamps from this coprocessor are in the continuous timebase.
196 */
197 KDCP_CONTINUOUS_TIME = 0x001,
198});
199
200typedef void (*kd_callback_fn)(void *context, kd_callback_type reason,
201 void *arg);
202
203/*
204 * Register a coprocessor for participation in tracing.
205 *
206 * The `callback` function will be called with the provided `context` when
207 * necessary, according to the `kd_callback_type`s.
208 *
209 * The positive core ID is returned on success, or -1 on failure.
210 */
211int kdebug_register_coproc(const char *name, kdebug_coproc_flags_t flags,
212 kd_callback_fn callback, void *context);
213
214void kernel_debug_enter(uint32_t coreid, uint32_t debugid, uint64_t timestamp,
215 uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4,
216 uintptr_t threadid);
217
218/*
219 * Legacy definitions for the prior IOP tracing.
220 */
221
222struct kd_callback {
223 kd_callback_fn func;
224 void *context;
225 /* name of IOP, NUL-terminated */
226 char iop_name[8];
227};
228typedef struct kd_callback kd_callback_t;
229
230__kpi_deprecated("use kdebug_register_coproc instead")
231int kernel_debug_register_callback(kd_callback_t callback);
232
233#pragma mark - internals
234
235#define KDBG_(f, x, a, b, c, d, n, ...) KDBG##n(f, x, a, b, c, d)
236#define KDBG0(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, 0, 0, 0, 0, 0)
237#define KDBG1(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, a, 0, 0, 0, 0)
238#define KDBG2(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, a, b, 0, 0, 0)
239#define KDBG3(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, a, b, c, 0, 0)
240#define KDBG4(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, a, b, c, d, 0)
241
242#ifdef XNU_KERNEL_PRIVATE
243#define KDBG_IMPROBABLE __improbable
244#else
245#define KDBG_IMPROBABLE
246#endif
247
248extern unsigned int kdebug_enable;
249
250/*
251 * The kernel debug configuration level. These values control which events are
252 * compiled in under different build configurations.
253 *
254 * Infer the supported kernel debug event level from config option. Use
255 * (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) as a guard to protect unaudited debug
256 * code.
257 */
258#define KDEBUG_LEVEL_NONE 0
259#define KDEBUG_LEVEL_IST 1
260#define KDEBUG_LEVEL_STANDARD 2
261#define KDEBUG_LEVEL_FULL 3
262
263#if NO_KDEBUG
264#define KDEBUG_LEVEL KDEBUG_LEVEL_NONE
265#elif IST_KDEBUG
266#define KDEBUG_LEVEL KDEBUG_LEVEL_IST
267#elif KDEBUG
268#define KDEBUG_LEVEL KDEBUG_LEVEL_FULL
269#else
270#define KDEBUG_LEVEL KDEBUG_LEVEL_STANDARD
271/*
272 * Currently, all other kernel configurations (development, etc) build with
273 * KDEBUG_LEVEL_STANDARD.
274 */
275#endif
276
277/*
278 * KERNEL_DEBUG_CONSTANT_FILTERED events are omitted from tracing unless they
279 * are explicitly requested in the typefilter. They are not emitted when
280 * tracing without a typefilter.
281 */
282#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD)
283#define KERNEL_DEBUG_CONSTANT_FILTERED(x, a, b, c, d, ...) \
284 do { \
285 if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \
286 kernel_debug_filtered((x), (uintptr_t)(a), (uintptr_t)(b), \
287 (uintptr_t)(c), (uintptr_t)(d)); \
288 } \
289 } while (0)
290#else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) */
291#define KERNEL_DEBUG_CONSTANT_FILTERED(type, x, a, b, c, d, ...) do {} while (0)
292#endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) */
293
294#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
295#define KERNEL_DEBUG_CONSTANT_RELEASE_NOPROCFILT(x, a, b, c, d, ...) \
296 do { \
297 if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \
298 kernel_debug_flags((x), (uintptr_t)(a), (uintptr_t)(b), \
299 (uintptr_t)(c), (uintptr_t)(d), KDBG_FLAG_NOPROCFILT); \
300 } \
301 } while (0)
302#else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
303#define KERNEL_DEBUG_CONSTANT_RELEASE_NOPROCFILT(x, a, b, c, d, ...) \
304 do { } while (0)
305#endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
306
307
308#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD)
309#define KERNEL_DEBUG_CONSTANT(x, a, b, c, d, e) \
310 do { \
311 if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \
312 kernel_debug((x), (uintptr_t)(a), (uintptr_t)(b), (uintptr_t)(c), \
313 (uintptr_t)(d),(uintptr_t)(e)); \
314 } \
315 } while (0)
316
317/*
318 * DO NOT USE THIS MACRO -- it breaks fundamental assumptions about ktrace and
319 * is only meant to be used by the pthread kext and other points in the kernel
320 * where the thread ID must be provided explicitly.
321 */
322#define KERNEL_DEBUG_CONSTANT1(x, a, b, c, d, e) \
323 do { \
324 if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \
325 kernel_debug1((x), (uintptr_t)(a), (uintptr_t)(b), (uintptr_t)(c), \
326 (uintptr_t)(d), (uintptr_t)(e)); \
327 } \
328 } while (0)
329
330#else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) */
331#define KERNEL_DEBUG_CONSTANT(x, a, b, c, d, e) do {} while (0)
332#define KERNEL_DEBUG_CONSTANT1(x, a, b, c, d, e) do {} while (0)
333#endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) */
334
335/*
336 * KERNEL_DEBUG_CONSTANT_IST (in-system trace) events provide an audited subset
337 * of tracepoints for userland system tracing tools. This tracing level was
338 * created by 8857227 to protect fairplayd and other PT_DENY_ATTACH processes.
339 * It has two effects: only KERNEL_DEBUG_CONSTANT_IST() traces are emitted and
340 * any PT_DENY_ATTACH processes will only emit basic traces as defined by the
341 * kernel_debug_filter() routine.
342 */
343#define KERNEL_DEBUG_CONSTANT_RELEASE(x, a, b, c, d, e) \
344 KERNEL_DEBUG_CONSTANT_IST(~KDEBUG_ENABLE_PPT, x, a, b, c, d, 0)
345
346#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
347#define KERNEL_DEBUG_CONSTANT_IST(type, x, a, b, c, d, e) \
348 do { \
349 if (KDBG_IMPROBABLE(kdebug_enable & (type))) { \
350 kernel_debug((x), (uintptr_t)(a), (uintptr_t)(b), (uintptr_t)(c), \
351 (uintptr_t)(d), 0); \
352 } \
353 } while (0)
354
355#define KERNEL_DEBUG_CONSTANT_IST1(x, a, b, c, d, e) \
356 do { \
357 if (KDBG_IMPROBABLE(kdebug_enable)) { \
358 kernel_debug1((x), (uintptr_t)(a), (uintptr_t)(b), (uintptr_t)(c), \
359 (uintptr_t)(d), (uintptr_t)(e)); \
360 } \
361 } while (0)
362
363#define KERNEL_DEBUG_EARLY(x, a, b, c, d) \
364 do { \
365 kernel_debug_early((uint32_t)(x), (uintptr_t)(a), (uintptr_t)(b), \
366 (uintptr_t)(c), (uintptr_t)(d)); \
367 } while (0)
368
369#else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
370#define KERNEL_DEBUG_CONSTANT_IST(type, x, a, b, c, d, e) do {} while (0)
371#define KERNEL_DEBUG_CONSTANT_IST1(x, a, b, c, d, e) do {} while (0)
372#define KERNEL_DEBUG_EARLY(x, a, b, c, d) do {} while (0)
373#endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
374
375#if NO_KDEBUG
376#define __kdebug_constant_only __unused
377#endif
378
379/*
380 * KERNEL_DEBUG events are only traced for DEBUG kernels.
381 */
382#define KERNEL_DEBUG_CONSTANT_DEBUG(x, a, b, c, d, e) \
383 KERNEL_DEBUG(x, a, b, c, d, e)
384
385#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_FULL)
386#define __kdebug_only
387
388#undef KERNEL_DEBUG
389#define KERNEL_DEBUG(x, a, b, c, d, e) \
390 do { \
391 if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \
392 kernel_debug((uint32_t)(x), (uintptr_t)(a), (uintptr_t)(b), \
393 (uintptr_t)(c), (uintptr_t)(d), (uintptr_t)(e)); \
394 } \
395 } while (0)
396
397/*
398 * DO NOT USE THIS MACRO -- see warning above for KERNEL_DEBUG_CONSTANT1.
399 */
400#define KERNEL_DEBUG1(x, a, b, c, d, e) \
401 do { \
402 if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \
403 kernel_debug1((uint32_t)(x), (uintptr_t)(a), (uintptr_t)(b), \
404 (uintptr_t)(c), (uintptr_t)(d), (uintptr_t)(e)); \
405 } \
406 } while (0)
407
408#else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_FULL) */
409#define __kdebug_only __unused
410
411#undef KERNEL_DEBUG
412#define KERNEL_DEBUG(x, a, b, c, d, e) do {} while (0)
413#define KERNEL_DEBUG1(x, a, b, c, d, e) do {} while (0)
414#endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_FULL) */
415
416void kernel_debug(uint32_t debugid, uintptr_t arg1, uintptr_t arg2,
417 uintptr_t arg3, uintptr_t arg4, uintptr_t arg5);
418
419void kernel_debug1(uint32_t debugid, uintptr_t arg1, uintptr_t arg2,
420 uintptr_t arg3, uintptr_t arg4, uintptr_t arg5);
421
422#define KDBG_FLAG_FILTERED 0x01
423#define KDBG_FLAG_NOPROCFILT 0x02
424
425void kernel_debug_flags(uint32_t debugid, uintptr_t arg1, uintptr_t arg2,
426 uintptr_t arg3, uintptr_t arg4, uint64_t flags);
427
428void kernel_debug_filtered(uint32_t debugid, uintptr_t arg1, uintptr_t arg2,
429 uintptr_t arg3, uintptr_t arg4);
430
431#pragma mark - xnu API
432
433#ifdef XNU_KERNEL_PRIVATE
434
435void kdebug_startup(void);
436
437/* Used in early boot to log events. */
438void kernel_debug_early(uint32_t debugid, uintptr_t arg1, uintptr_t arg2,
439 uintptr_t arg3, uintptr_t arg4);
440/* Used in early boot to log strings spanning only a single tracepoint. */
441void kernel_debug_string_early(const char *message);
442/* Used to trace strings within kdebug tracepoints on arbitrary eventids. */
443void kernel_debug_string_simple(uint32_t eventid, const char *str);
444/* Only used by ktrace to reset kdebug. ktrace_lock must be held. */
445extern void kdebug_reset(void);
446
447void kdbg_dump_trace_to_file(const char *, bool reenable);
448
449enum kdebug_opts {
450 KDOPT_WRAPPING = 0x1,
451 KDOPT_ATBOOT = 0x2,
452};
453
454enum kdebug_mode {
455 KDEBUG_MODE_TRACE = 0x1, /* General purpose tracing.*/
456 KDEBUG_MODE_TRIAGE = 0x2, /* Collect more information to triage failures / gain insight into in-kernel operations of a thread.*/
457};
458
459
460int kdbg_bootstrap(bool early_trace, int mode);
461void kdebug_init(unsigned int n_events, char *filterdesc,
462 enum kdebug_opts opts);
463void kdebug_trace_start(unsigned int n_events, const char *filterdesc,
464 enum kdebug_opts opts);
465uint64_t kdebug_wake(void);
466void kdebug_free_early_buf(void);
467
468
469struct proc;
470void kdbg_trace_data(struct proc *proc, long *arg_pid, long *arg_uniqueid);
471
472#define KDBG_VFS_LOOKUP_FLAG_LOOKUP 0x01
473#define KDBG_VFS_LOOKUP_FLAG_NOPROCFILT 0x02
474void kdebug_vfs_lookup(unsigned long *path_words, int path_len, void *vnp,
475 uint32_t flags);
476
477void ktriage_extract(uint64_t thread_id, void *buf, uint32_t bufsz);
478
479#endif /* XNU_KERNEL_PRIVATE */
480
481#ifdef KERNEL_PRIVATE
482
483typedef struct ktriage_strings {
484 int num_strings;
485 const char **strings;
486} ktriage_strings_t;
487
488int ktriage_register_subsystem_strings(uint8_t subsystem, ktriage_strings_t *subsystem_strings);
489int ktriage_unregister_subsystem_strings(uint8_t subsystem);
490
491void ktriage_record(uint64_t thread_id, uint64_t debugid, uintptr_t arg);
492
493#define NUMPARMS 23
494void kdebug_lookup_gen_events(long *path_words, int path_len, void *vnp,
495 bool lookup);
496
497#pragma mark - EnergyTracing
498
499#define KERNEL_DBG_IST_SANE KDBG_RELEASE
500#define ENTR_KDTRACEFUNC KDBG_RELEASE
501
502// value is int64_t, quality is uint32_t
503#define KERNEL_ENERGYTRACE(opcode, lifespan, id, quality, value) \
504 ENTR_KDTRACE(kEnTrCompKernel, opcode, lifespan, id, \
505 quality, value)
506#define KERNEL_ENTR_ASSOCIATE(par_opcode, par_act_id, sub_opcode, sub_act_id) \
507 ENTR_KDASSOCIATE(kEnTrCompKernel, par_opcode, par_act_id, \
508 kEnTrCompKernel, sub_opcode, sub_act_id)
509
510#endif /* KERNEL_PRIVATE */
511
512#endif /* KERNEL */
513
514__END_DECLS
515
516#endif /* !defined(BSD_SYS_KDEBUG_KERNEL_H) */
517