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