1 /*
2 * Copyright (c) 2015-2021 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 #ifndef __os_log_h
25 #define __os_log_h
26
27 #include <os/object.h>
28 #include <stdint.h>
29 #include <stdbool.h>
30
31 #ifndef __has_attribute
32 #define __has_attribute(x) 0
33 #endif
34
35 #ifndef __has_builtin
36 #define __has_builtin(x) 0
37 #endif
38
39 #if __has_attribute(not_tail_called)
40 #define OS_LOG_NOTAILCALL __attribute__((not_tail_called))
41 #define OS_LOG_NOTAILCALL_MARKER
42 #else
43 #define OS_LOG_NOTAILCALL
44 #define OS_LOG_NOTAILCALL_MARKER __asm__("")
45 #endif
46
47 __BEGIN_DECLS
48
49 extern void *__dso_handle;
50
51 #ifdef XNU_KERNEL_PRIVATE
52 extern bool startup_serial_logging_active;
53 extern uint64_t startup_serial_num_procs;
54 #endif /* XNU_KERNEL_PRIVATE */
55
56 #ifdef KERNEL
57 #define OS_LOG_BUFFER_MAX_SIZE 256
58 #else
59 #define OS_LOG_BUFFER_MAX_SIZE 1024
60 #endif
61
62 // The OS_LOG_BUFFER_MAX_SIZE limit includes the metadata that
63 // must be included in the os_log firehose buffer
64 #define OS_LOG_DATA_MAX_SIZE (OS_LOG_BUFFER_MAX_SIZE - 16)
65
66 OS_ALWAYS_INLINE static inline void _os_log_verify_format_str(__unused const char *msg, ...) __attribute__((format(os_log, 1, 2)));
67 OS_ALWAYS_INLINE static inline void
_os_log_verify_format_str(__unused const char * msg,...)68 _os_log_verify_format_str(__unused const char *msg, ...) /* placeholder */
69 {
70 }
71
72 #if OS_OBJECT_USE_OBJC
73 OS_OBJECT_DECL(os_log);
74 #else
75 typedef struct os_log_s *os_log_t;
76 #endif /* OS_OBJECT_USE_OBJC */
77
78 /*!
79 * @const OS_LOG_DISABLED
80 *
81 * @discussion
82 * Use this to disable a specific log message.
83 */
84 #define OS_LOG_DISABLED NULL
85
86 /*!
87 * @const OS_LOG_DEFAULT
88 *
89 * @discussion
90 * Use this to log a message in accordance with current system settings.
91 */
92 #define OS_LOG_DEFAULT OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_default)
93 __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0)
94 OS_EXPORT
95 struct os_log_s _os_log_default;
96
97 /*!
98 * @enum os_log_type_t
99 *
100 * @discussion
101 * Supported log message types.
102 *
103 * @constant OS_LOG_TYPE_DEFAULT
104 * Equivalent type for "os_log()" messages, i.e., default messages that are always
105 * captured to memory or disk.
106 *
107 * @constant OS_LOG_TYPE_INFO
108 * Equivalent type for "os_log_info()" messages, i.e., Additional informational messages.
109 *
110 * @constant OS_LOG_TYPE_DEBUG
111 * Equivalent type for "os_log_debug()" messages, i.e., Debug messages.
112 *
113 * @constant OS_LOG_TYPE_ERROR
114 * Equivalent type for "os_log_error()" messages, i.e., local process error messages.
115 *
116 * @constant OS_LOG_TYPE_FAULT
117 * Equivalent type for "os_log_fault()" messages, i.e., a system error that involves
118 * potentially more than one process, usually used by daemons and services.
119 */
120 OS_ENUM(os_log_type, uint8_t,
121 OS_LOG_TYPE_DEFAULT = 0x00,
122 OS_LOG_TYPE_INFO = 0x01,
123 OS_LOG_TYPE_DEBUG = 0x02,
124 OS_LOG_TYPE_ERROR = 0x10,
125 OS_LOG_TYPE_FAULT = 0x11);
126
127 /*!
128 * @function os_log_create
129 *
130 * @abstract
131 * Creates a log object to be used with other log related functions.
132 *
133 * @discussion
134 * Creates a log object to be used with other log related functions. The
135 * log object serves two purposes: (1) tag related messages by subsystem
136 * and category name for easy filtering, and (2) control logging system
137 * behavior for messages.
138 *
139 * A log object may customize logging system behavior for its messages by
140 * adding a configuration file in /Library/LogPreferences. Most options
141 * accept 3 values: "Default", "Yes" or "No" as strings, where "Default"
142 * signifies follow system behavior for the level of messages.
143 *
144 * For log:
145 *
146 * os_log_create("com.company.mysubsystem", "connections");
147 *
148 * System-provided preferences are located in /System/Library/LogPreferences/<subsystem>.plist
149 *
150 * <dict>
151 *
152 * <!-- Default options applied to message types in each category, which can be overriden. -->
153 * <key>DEFAULT-OPTIONS</key>
154 * <dict>
155 * <key>Enabled</key> <!-- Enabled state follows system defaults -->
156 * <string>Default</string>
157 * <key>Persist</key> <!-- Do not persist to disk, use memory-only buffer if enabled -->
158 * <string>No</string>
159 * <key>TTL</key> <!-- Follow system default behavior if persistence is enabled -->
160 * <string>Default</string> <!-- Can specify in days with "d" or hours "h" (e.g., "4h" = 4 hours) -->
161 * </dict>
162 *
163 * <!-- category named “connections” -->
164 * <key>connections</key>
165 * <dict>
166 *
167 * <!-- Options that control "os_log()" behavior. The "Enabled" option is ignored. -->
168 * <key>Default</key>
169 * <dict>
170 * <key>Persist</key> <!-- Always persist to disk -->
171 * <string>Yes</string>
172 * <key>TTL</key> <!-- Store default messages for maximum 4 days -->
173 * <integer>4d</integer>
174 * </dict>
175 *
176 * <!-- Subdictionary of options that control "os_log_info()" behavior -->
177 * <key>Info</key>
178 * <dict>
179 * <key>Persist</key> <!-- If enabled persist to disk -->
180 * <string>Yes</string>
181 * <key>TTL</key> <!-- Store Info messages for 2 days -->
182 * <string>2d</string>
183 * </dict>
184 *
185 * <!-- Subdictionary of options that control "os_log_debug()" behavior -->
186 * <key>Debug</key>
187 * <dict>
188 * <key>Enabled</key> <!-- Not enabled, must be enabled specifically -->
189 * <string>No</string>
190 * </dict>
191 * </dict>
192 * </dict>
193 *
194 * All other preferences and system-overrides are stored in /Library/LogPreferences/.
195 *
196 * @param subsystem
197 * The identifier of the given subsystem should be in reverse DNS form
198 * (i.e., com.company.mysubsystem). This string must be a constant string,
199 * not dynamically generated.
200 *
201 * @param category
202 * The category within the given subsystem that specifies the settings for
203 * the log object. This string must be a constant string, not dynamically
204 * generated.
205 *
206 * @result
207 * Returns an os_log_t value to be passed to other os_log API calls. This
208 * should be called once at log initialization and rely on system to detect
209 * changes to settings. This object should be released when no longer used
210 * via os_release or -[release] method.
211 *
212 * A value will always be returned to allow for dynamic enablement.
213 */
214 __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0)
215 OS_EXPORT OS_NOTHROW OS_WARN_RESULT OS_OBJECT_RETURNS_RETAINED
216 os_log_t
217 os_log_create(const char *subsystem, const char *category);
218
219 /*!
220 * @function os_log_info_enabled
221 *
222 * @abstract
223 * Returns if additional information log messages are enabled for a particular
224 * log object.
225 *
226 * @discussion
227 * Returns if additional information log messages are enabled for a particular
228 * log object.
229 *
230 * @param log
231 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
232 *
233 * @result
234 * Returns ‘true’ if additional information log messages are enabled.
235 */
236 __WATCHOS_AVAILABLE(3.0) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0)
237 OS_EXPORT OS_NOTHROW OS_WARN_RESULT
238 bool
239 os_log_info_enabled(os_log_t log);
240
241 /*!
242 * @function os_log_debug_enabled
243 *
244 * @abstract
245 * Returns if debug log messages are enabled for a particular log object.
246 *
247 * @discussion
248 * Returns if debug log messages are enabled for a particular log object.
249 *
250 * @param log
251 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
252 *
253 * @result
254 * Returns ‘true’ if debug log messages are enabled.
255 */
256 __WATCHOS_AVAILABLE(3.0) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0)
257 OS_EXPORT OS_NOTHROW OS_WARN_RESULT
258 bool
259 os_log_debug_enabled(os_log_t log);
260
261 /*!
262 * @function os_log
263 *
264 * @abstract
265 * Insert a log message into the Unified Logging and Tracing system.
266 *
267 * @discussion
268 * Insert a log message into the Unified Logging and Tracing system in
269 * accordance with the preferences specified by the provided log object.
270 * These messages cannot be disabled and therefore always captured either
271 * to memory or disk.
272 *
273 * When an os_activity_id_t is present, the log message will also be scoped by
274 * that identifier. Activities provide granular filtering of log messages
275 * across threads and processes.
276 *
277 * There is a physical cap of 256 bytes per entry for dynamic content,
278 * i.e., %s and %@, that can be written to the persistence store. As such,
279 * all content exceeding the limit will be truncated before written to disk.
280 * Live streams will continue to show the full content.
281 *
282 * @param log
283 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
284 *
285 * @param format
286 * A format string to generate a human-readable log message when the log
287 * line is decoded. This string must be a constant string, not dynamically
288 * generated. Supports all standard printf types and %@ (objects).
289 */
290 #define os_log(log, format, ...) __extension__({ \
291 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
292 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
293 _os_log_verify_format_str(format, ##__VA_ARGS__); \
294 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_DEFAULT, _os_log_fmt, ##__VA_ARGS__); \
295 __asm__(""); /* avoid tailcall */ \
296 })
297
298 /*!
299 * @function os_log_info
300 *
301 * @abstract
302 * Insert a development log message into the Unified Logging and Tracing system.
303 *
304 * @discussion
305 * Insert a log message into the Unified Logging and Tracing system in
306 * accordance with the preferences specified by the provided log object.
307 *
308 * When an os_activity_id_t is present, the log message will also be scoped by
309 * that identifier. Activities provide granular filtering of log messages
310 * across threads and processes.
311 *
312 * There is a physical cap of 256 bytes per entry for dynamic content,
313 * i.e., %s and %@, that can be written to the persistence store. As such,
314 * all content exceeding the limit will be truncated before written to disk.
315 * Live streams will continue to show the full content.
316 *
317 * @param log
318 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
319 *
320 * @param format
321 * A format string to generate a human-readable log message when the log
322 * line is decoded. This string must be a constant string, not dynamically
323 * generated. Supports all standard printf types and %@ (objects).
324 */
325 #define os_log_info(log, format, ...) __extension__({ \
326 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
327 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
328 _os_log_verify_format_str(format, ##__VA_ARGS__); \
329 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_INFO, _os_log_fmt, ##__VA_ARGS__); \
330 __asm__(""); /* avoid tailcall */ \
331 })
332
333 /*!
334 * @function os_log_debug
335 *
336 * @abstract
337 * Insert a debug log message into the Unified Logging and Tracing system.
338 *
339 * @discussion
340 * Insert a debug log message into the Unified Logging and Tracing system in
341 * accordance with the preferences specified by the provided log object.
342 *
343 * When an os_activity_id_t is present, the log message will also be scoped by
344 * that identifier. Activities provide granular filtering of log messages
345 * across threads and processes.
346 *
347 * There is a physical cap of 256 bytes per entry for dynamic content,
348 * i.e., %s and %@, that can be written to the persistence store. As such,
349 * all content exceeding the limit will be truncated before written to disk.
350 * Live streams will continue to show the full content.
351 *
352 * @param log
353 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
354 *
355 * @param format
356 * A format string to generate a human-readable log message when the log
357 * line is decoded. This string must be a constant string, not dynamically
358 * generated. Supports all standard printf types and %@ (objects).
359 */
360 #define os_log_debug(log, format, ...) __extension__({ \
361 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
362 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
363 _os_log_verify_format_str(format, ##__VA_ARGS__); \
364 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_DEBUG, _os_log_fmt, ##__VA_ARGS__); \
365 __asm__(""); /* avoid tailcall */ \
366 })
367
368 /*!
369 * @function os_log_error
370 *
371 * @abstract
372 * Insert an error log message into the Unified Logging and Tracing system.
373 *
374 * @discussion
375 * Insert an error log message into the Unified Logging and Tracing system.
376 *
377 * When an os_activity_id_t is present, the log message will also be scoped by
378 * that identifier. Activities provide granular filtering of log messages
379 * across threads and processes.
380 *
381 * There is a physical cap of 256 bytes per entry for dynamic content,
382 * i.e., %s and %@, that can be written to the persistence store. As such,
383 * all content exceeding the limit will be truncated before written to disk.
384 * Live streams will continue to show the full content.
385 *
386 * @param log
387 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
388 *
389 * @param format
390 * A format string to generate a human-readable log message when the log
391 * line is decoded. This string must be a constant string, not dynamically
392 * generated. Supports all standard printf types and %@ (objects).
393 */
394 #define os_log_error(log, format, ...) __extension__({ \
395 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
396 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
397 _os_log_verify_format_str(format, ##__VA_ARGS__); \
398 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_ERROR, _os_log_fmt, ##__VA_ARGS__); \
399 __asm__(""); /* avoid tailcall */ \
400 })
401
402 /*!
403 * @function os_log_fault
404 *
405 * @abstract
406 * Insert a fault log message into the Unified Logging and Tracing system.
407 *
408 * @discussion
409 * Log a fault message issue into the Unified Logging and Tracing system
410 * signifying a multi-process (i.e., system error) related issue, either
411 * due to interaction via IPC or some other. Faults will gather information
412 * from the entire process chain and record it for later inspection.
413 *
414 * When an os_activity_id_t is present, the log message will also be scoped by
415 * that identifier. Activities provide granular filtering of log messages
416 * across threads and processes.
417 *
418 * There is a physical cap of 256 bytes per entry for dynamic content,
419 * i.e., %s and %@, that can be written to the persistence store. As such,
420 * all content exceeding the limit will be truncated before written to disk.
421 * Live streams will continue to show the full content.
422 *
423 * @param log
424 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
425 *
426 * @param format
427 * A format string to generate a human-readable log message when the log
428 * line is decoded. This string must be a constant string, not dynamically
429 * generated. Supports all standard printf types and %@ (objects).
430 */
431 #define os_log_fault(log, format, ...) __extension__({ \
432 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
433 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
434 _os_log_verify_format_str(format, ##__VA_ARGS__); \
435 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_FAULT, _os_log_fmt, ##__VA_ARGS__); \
436 __asm__(""); /* avoid tailcall */ \
437 })
438
439 /*!
440 * @function os_log_with_type
441 *
442 * @abstract
443 * Log a message using a specific type.
444 *
445 * @discussion
446 * Will log a message with the provided os_log_type_t.
447 *
448 * @param log
449 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
450 *
451 * @param type
452 * Pass a valid type from os_log_type_t.
453 *
454 * @param format
455 * A format string to generate a human-readable log message when the log
456 * line is decoded. This string must be a constant string, not dynamically
457 * generated. Supports all standard printf types and %@ (objects).
458 */
459 #define os_log_with_type(log, type, format, ...) __extension__({ \
460 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
461 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
462 _os_log_verify_format_str(format, ##__VA_ARGS__); \
463 _os_log_internal(&__dso_handle, log, type, _os_log_fmt, ##__VA_ARGS__); \
464 __asm__(""); /* avoid tailcall */ \
465 })
466
467 /*!
468 * @function os_log_driverKit
469 *
470 * @abstract
471 * Log a message using a specific type. This variant should be called only from dexts.
472 *
473 * @discussion
474 * Will log a message with the provided os_log_type_t.
475 *
476 * @param log
477 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
478 *
479 * @param type
480 * Pass a valid type from os_log_type_t.
481 *
482 * @param format
483 * A format string to generate a human-readable log message when the log
484 * line is decoded. This string must be a constant string, not dynamically
485 * generated. Supports all standard printf types and %@ (objects).
486 *
487 * @result
488 * Returns EPERM if the caller is not a driverKit process, 0 in case of success.
489 */
490 #define os_log_driverKit(out, log, type, format, ...) __extension__({ \
491 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
492 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
493 _os_log_verify_format_str(format, ##__VA_ARGS__); \
494 (*(out)) = _os_log_internal_driverKit(&__dso_handle, log, type, _os_log_fmt, ##__VA_ARGS__); \
495 __asm__(""); /* avoid tailcall */ \
496 })
497
498 /*!
499 * @function os_log_coprocessor
500 *
501 * @abstract
502 * IOP logging function, intended for use by RTBuddy for
503 * coprocessor os log functionality only.
504 */
505 bool
506 os_log_coprocessor(void *buff, uint64_t buff_len, os_log_type_t type,
507 const char *uuid, uint64_t timestamp, uint32_t offset, bool stream_log);
508
509 /*!
510 * @function os_log_coprocessor_register
511 *
512 * @abstract
513 * IOP metadata registration, intended for use by RTBuddy for
514 * coprocessor os log functionality only.
515 * Will be removed after all user code will be updated to use os_log_coprocessor_register_with_type
516 */
517 void
518 os_log_coprocessor_register(const char *uuid, const char *file_path, bool copy);
519
520 typedef enum {
521 os_log_coproc_register_memory,
522 os_log_coproc_register_harvest_fs_img4,
523 os_log_coproc_register_harvest_fs_ftab,
524 } os_log_coproc_reg_t;
525
526 /*!
527 * @function os_log_coprocessor_register_with_type
528 *
529 * @abstract
530 * IOP metadata registration, intended for use by RTBuddy for
531 * coprocessor os log functionality only.
532 */
533 void
534 os_log_coprocessor_register_with_type(const char *uuid, const char *file_path, os_log_coproc_reg_t register_type);
535
536 /*!
537 * @function os_log_sensitive_debug
538 *
539 * @abstract
540 * Insert a debug log message containing sensitive content (i.e., personal
541 * identifying information).
542 *
543 * @discussion
544 * Insert a debug log message containing sensitive content (i.e., personal
545 * identifying information) in accordance with the preferences specified by
546 * the provided log object.
547 *
548 * All strings are considered potentially sensitive, though this call
549 * specifically signifies the message as containing sensitive content.
550 * The message will be stored separately from other messages.
551 *
552 * When an os_activity_id_t is present, the log message will also be scoped by
553 * that identifier. Activities provide granular filtering of log messages
554 * across threads and processes.
555 *
556 * There is a physical cap of 256 bytes per entry for dynamic content,
557 * i.e., %s and %@, that can be written to the persistence store. As such,
558 * all content exceeding the limit will be truncated before written to disk.
559 * Live streams will continue to show the full content.
560 *
561 * @param log
562 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
563 *
564 * @param format
565 * A format string to generate a human-readable log message when the log
566 * line is decoded. This string must be a constant string, not dynamically
567 * generated. Supports all standard printf types and %@ (objects).
568 */
569 #define os_log_sensitive_debug(log, format, ...) __extension__({ \
570 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
571 __attribute__((section("__TEXT,__os_log_sens"))) static const char _os_log_fmt[] = format; \
572 _os_log_verify_format_str(format, ##__VA_ARGS__); \
573 _os_log_sensitive(&__dso_handle, log, OS_LOG_TYPE_DEBUG, _os_log_fmt, ##__VA_ARGS__); \
574 __asm__(""); /* avoid tailcall */ \
575 })
576
577 #ifdef XNU_KERNEL_PRIVATE
578 #define os_log_with_startup_serial(log, format, ...) __extension__({ \
579 if (startup_serial_logging_active) { printf(format, ##__VA_ARGS__); } \
580 else { os_log(log, format, ##__VA_ARGS__); } \
581 })
582 #endif /* XNU_KERNEL_PRIVATE */
583
584 /*!
585 * @function _os_log_internal
586 *
587 * @abstract
588 * Internal function used by macros.
589 */
590 __WATCHOS_AVAILABLE(3.0) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0)
591 OS_EXPORT OS_NOTHROW
592 void
593 _os_log_internal(void *dso, os_log_t log, os_log_type_t type, const char *message, ...);
594
595 /*!
596 * @function _os_log_internal_driverKit
597 *
598 * @abstract
599 * Internal function used by macros.
600 */
601 __WATCHOS_AVAILABLE(6.0) __OSX_AVAILABLE(10.15) __IOS_AVAILABLE(13.0) __TVOS_AVAILABLE(13.0)
602 OS_EXPORT OS_NOTHROW
603 int
604 _os_log_internal_driverKit(void *dso, os_log_t log, os_log_type_t type, const char *message, ...);
605 __END_DECLS
606
607 #endif /* __os_log_h */
608