1*43a90889SApple OSS Distributions /*
2*43a90889SApple OSS Distributions * Copyright (c) 2019-2024 Apple Inc. All rights reserved.
3*43a90889SApple OSS Distributions */
4*43a90889SApple OSS Distributions
5*43a90889SApple OSS Distributions #undef offset
6*43a90889SApple OSS Distributions
7*43a90889SApple OSS Distributions #include <kern/cpu_data.h>
8*43a90889SApple OSS Distributions #include <os/base.h>
9*43a90889SApple OSS Distributions #include <os/hash.h>
10*43a90889SApple OSS Distributions #include <os/object.h>
11*43a90889SApple OSS Distributions #include <os/log.h>
12*43a90889SApple OSS Distributions #include <stdbool.h>
13*43a90889SApple OSS Distributions #include <stddef.h>
14*43a90889SApple OSS Distributions #include <stdint.h>
15*43a90889SApple OSS Distributions
16*43a90889SApple OSS Distributions #include <vm/vm_kern_xnu.h>
17*43a90889SApple OSS Distributions #include <mach/vm_statistics.h>
18*43a90889SApple OSS Distributions #include <kern/debug.h>
19*43a90889SApple OSS Distributions #include <libkern/libkern.h>
20*43a90889SApple OSS Distributions #include <libkern/kernel_mach_header.h>
21*43a90889SApple OSS Distributions #include <pexpert/pexpert.h>
22*43a90889SApple OSS Distributions #include <uuid/uuid.h>
23*43a90889SApple OSS Distributions #include <sys/msgbuf.h>
24*43a90889SApple OSS Distributions
25*43a90889SApple OSS Distributions #include <mach/mach_time.h>
26*43a90889SApple OSS Distributions #include <kern/thread.h>
27*43a90889SApple OSS Distributions #include <kern/simple_lock.h>
28*43a90889SApple OSS Distributions #include <kern/kalloc.h>
29*43a90889SApple OSS Distributions #include <kern/clock.h>
30*43a90889SApple OSS Distributions #include <kern/assert.h>
31*43a90889SApple OSS Distributions #include <kern/smr_hash.h>
32*43a90889SApple OSS Distributions #include <kern/startup.h>
33*43a90889SApple OSS Distributions #include <kern/task.h>
34*43a90889SApple OSS Distributions
35*43a90889SApple OSS Distributions #include <firehose/firehose_types_private.h>
36*43a90889SApple OSS Distributions #include <firehose/tracepoint_private.h>
37*43a90889SApple OSS Distributions #include <firehose/chunk_private.h>
38*43a90889SApple OSS Distributions #include <os/firehose_buffer_private.h>
39*43a90889SApple OSS Distributions #include <os/firehose.h>
40*43a90889SApple OSS Distributions #include <os/log_private.h>
41*43a90889SApple OSS Distributions
42*43a90889SApple OSS Distributions #include "log_encode.h"
43*43a90889SApple OSS Distributions #include "log_internal.h"
44*43a90889SApple OSS Distributions #include "log_mem.h"
45*43a90889SApple OSS Distributions #include "log_queue.h"
46*43a90889SApple OSS Distributions #include "trace_internal.h"
47*43a90889SApple OSS Distributions
48*43a90889SApple OSS Distributions #define OS_LOGMEM_BUF_ORDER 14
49*43a90889SApple OSS Distributions #define OS_LOGMEM_MIN_LOG_ORDER 9
50*43a90889SApple OSS Distributions #define OS_LOGMEM_MAX_LOG_ORDER (OS_LOG_MAX_SIZE_ORDER)
51*43a90889SApple OSS Distributions
52*43a90889SApple OSS Distributions #define OS_LOG_SUBSYSTEM_MAX_CNT 1024
53*43a90889SApple OSS Distributions #define OS_LOG_SUBSYSTEM_NONE 0xffff
54*43a90889SApple OSS Distributions #define OS_LOG_SUBSYSTEM_BASE 0x0001 // OS_LOG_DEFAULT takes 0 by definition
55*43a90889SApple OSS Distributions #define OS_LOG_SUBSYSTEM_LAST (OS_LOG_SUBSYSTEM_BASE + OS_LOG_SUBSYSTEM_MAX_CNT)
56*43a90889SApple OSS Distributions #define OS_LOG_SUBSYSTEM_NAME_MAX_LEN 128
57*43a90889SApple OSS Distributions
58*43a90889SApple OSS Distributions /*
59*43a90889SApple OSS Distributions * OSLog subsystem type. The struct layout matches its libtrace counterpart
60*43a90889SApple OSS Distributions * and also matches what libtrace (logd) expects from subsystem registration
61*43a90889SApple OSS Distributions * metadata payload.
62*43a90889SApple OSS Distributions */
63*43a90889SApple OSS Distributions struct os_log_subsystem_s {
64*43a90889SApple OSS Distributions uint16_t ols_id;
65*43a90889SApple OSS Distributions union {
66*43a90889SApple OSS Distributions struct {
67*43a90889SApple OSS Distributions uint8_t ols_sub_size;
68*43a90889SApple OSS Distributions uint8_t ols_cat_size;
69*43a90889SApple OSS Distributions };
70*43a90889SApple OSS Distributions uint16_t ols_sizes;
71*43a90889SApple OSS Distributions };
72*43a90889SApple OSS Distributions char ols_name[2 * OS_LOG_SUBSYSTEM_NAME_MAX_LEN];
73*43a90889SApple OSS Distributions };
74*43a90889SApple OSS Distributions
75*43a90889SApple OSS Distributions struct os_log_s {
76*43a90889SApple OSS Distributions struct os_log_subsystem_s ol_subsystem;
77*43a90889SApple OSS Distributions struct smrq_slink ol_hash_link;
78*43a90889SApple OSS Distributions };
79*43a90889SApple OSS Distributions
80*43a90889SApple OSS Distributions struct os_log_s _os_log_default;
81*43a90889SApple OSS Distributions struct os_log_s _os_log_replay;
82*43a90889SApple OSS Distributions
83*43a90889SApple OSS Distributions /* Counters for persistence mode */
84*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_total_msgcount);
85*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_metadata_saved_msgcount);
86*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_metadata_dropped_msgcount);
87*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_signpost_saved_msgcount);
88*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_signpost_dropped_msgcount);
89*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_error_count);
90*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_saved_msgcount);
91*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_dropped_msgcount);
92*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_boot_dropped_msgcount);
93*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_coprocessor_total_msgcount);
94*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_coprocessor_dropped_msgcount);
95*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_p_unresolved_kc_msgcount);
96*43a90889SApple OSS Distributions
97*43a90889SApple OSS Distributions /* Counters for msgbuf logging */
98*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_msgbuf_msgcount)
99*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_msgbuf_dropped_msgcount)
100*43a90889SApple OSS Distributions
101*43a90889SApple OSS Distributions /* Log subsystem counters */
102*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_subsystem_count);
103*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_subsystem_found);
104*43a90889SApple OSS Distributions SCALABLE_COUNTER_DEFINE(oslog_subsystem_dropped);
105*43a90889SApple OSS Distributions
106*43a90889SApple OSS Distributions LCK_GRP_DECLARE(oslog_cache_lock_grp, "oslog_cache_lock_grp");
107*43a90889SApple OSS Distributions LCK_TICKET_DECLARE(oslog_cache_lock, &oslog_cache_lock_grp);
108*43a90889SApple OSS Distributions
109*43a90889SApple OSS Distributions static bool oslog_boot_done = false;
110*43a90889SApple OSS Distributions static SECURITY_READ_ONLY_LATE(bool) oslog_disabled = false;
111*43a90889SApple OSS Distributions
112*43a90889SApple OSS Distributions static uint16_t os_log_subsystem_id = OS_LOG_SUBSYSTEM_BASE;
113*43a90889SApple OSS Distributions
114*43a90889SApple OSS Distributions static struct logmem_s os_log_mem;
115*43a90889SApple OSS Distributions static struct smr_hash os_log_cache;
116*43a90889SApple OSS Distributions
117*43a90889SApple OSS Distributions static struct firehose_chunk_s firehose_boot_chunk = {
118*43a90889SApple OSS Distributions .fc_pos = {
119*43a90889SApple OSS Distributions .fcp_next_entry_offs = offsetof(struct firehose_chunk_s, fc_data),
120*43a90889SApple OSS Distributions .fcp_private_offs = FIREHOSE_CHUNK_SIZE,
121*43a90889SApple OSS Distributions .fcp_refcnt = 1, // Indicate that there is a writer to this chunk
122*43a90889SApple OSS Distributions .fcp_stream = firehose_stream_persist,
123*43a90889SApple OSS Distributions .fcp_flag_io = 1, // Lets assume this is coming from the io bank
124*43a90889SApple OSS Distributions },
125*43a90889SApple OSS Distributions };
126*43a90889SApple OSS Distributions
127*43a90889SApple OSS Distributions bool os_log_disabled(void);
128*43a90889SApple OSS Distributions
129*43a90889SApple OSS Distributions extern vm_offset_t kernel_firehose_addr;
130*43a90889SApple OSS Distributions extern bool bsd_log_lock(bool);
131*43a90889SApple OSS Distributions extern void bsd_log_unlock(void);
132*43a90889SApple OSS Distributions extern void logwakeup(void);
133*43a90889SApple OSS Distributions extern void oslog_stream(bool, firehose_tracepoint_id_u, uint64_t, const void *, size_t);
134*43a90889SApple OSS Distributions extern void *OSKextKextForAddress(const void *);
135*43a90889SApple OSS Distributions
136*43a90889SApple OSS Distributions static bool
os_log_safe(void)137*43a90889SApple OSS Distributions os_log_safe(void)
138*43a90889SApple OSS Distributions {
139*43a90889SApple OSS Distributions return oslog_is_safe() || startup_phase < STARTUP_SUB_EARLY_BOOT;
140*43a90889SApple OSS Distributions }
141*43a90889SApple OSS Distributions
142*43a90889SApple OSS Distributions static bool
os_log_turned_off(void)143*43a90889SApple OSS Distributions os_log_turned_off(void)
144*43a90889SApple OSS Distributions {
145*43a90889SApple OSS Distributions return oslog_disabled || (atm_get_diagnostic_config() & ATM_TRACE_OFF);
146*43a90889SApple OSS Distributions }
147*43a90889SApple OSS Distributions
148*43a90889SApple OSS Distributions bool
os_log_info_enabled(os_log_t log __unused)149*43a90889SApple OSS Distributions os_log_info_enabled(os_log_t log __unused)
150*43a90889SApple OSS Distributions {
151*43a90889SApple OSS Distributions return !os_log_turned_off();
152*43a90889SApple OSS Distributions }
153*43a90889SApple OSS Distributions
154*43a90889SApple OSS Distributions bool
os_log_debug_enabled(os_log_t log __unused)155*43a90889SApple OSS Distributions os_log_debug_enabled(os_log_t log __unused)
156*43a90889SApple OSS Distributions {
157*43a90889SApple OSS Distributions return !os_log_turned_off();
158*43a90889SApple OSS Distributions }
159*43a90889SApple OSS Distributions
160*43a90889SApple OSS Distributions bool
os_log_disabled(void)161*43a90889SApple OSS Distributions os_log_disabled(void)
162*43a90889SApple OSS Distributions {
163*43a90889SApple OSS Distributions return oslog_disabled;
164*43a90889SApple OSS Distributions }
165*43a90889SApple OSS Distributions
166*43a90889SApple OSS Distributions static inline size_t
log_payload_priv_data_size(const log_payload_s * lp)167*43a90889SApple OSS Distributions log_payload_priv_data_size(const log_payload_s *lp)
168*43a90889SApple OSS Distributions {
169*43a90889SApple OSS Distributions assert3u(lp->lp_pub_data_size, <=, lp->lp_data_size);
170*43a90889SApple OSS Distributions return lp->lp_data_size - lp->lp_pub_data_size;
171*43a90889SApple OSS Distributions }
172*43a90889SApple OSS Distributions
173*43a90889SApple OSS Distributions static inline const uint8_t *
log_payload_priv_data(const log_payload_s * lp,const uint8_t * lp_data)174*43a90889SApple OSS Distributions log_payload_priv_data(const log_payload_s *lp, const uint8_t *lp_data)
175*43a90889SApple OSS Distributions {
176*43a90889SApple OSS Distributions if (log_payload_priv_data_size(lp) == 0) {
177*43a90889SApple OSS Distributions return NULL;
178*43a90889SApple OSS Distributions }
179*43a90889SApple OSS Distributions return &lp_data[lp->lp_pub_data_size];
180*43a90889SApple OSS Distributions }
181*43a90889SApple OSS Distributions
182*43a90889SApple OSS Distributions static void
log_payload_init(log_payload_t lp,firehose_stream_t stream,firehose_tracepoint_id_u ftid,uint64_t timestamp,size_t data_size,size_t pub_data_size)183*43a90889SApple OSS Distributions log_payload_init(log_payload_t lp, firehose_stream_t stream, firehose_tracepoint_id_u ftid,
184*43a90889SApple OSS Distributions uint64_t timestamp, size_t data_size, size_t pub_data_size)
185*43a90889SApple OSS Distributions {
186*43a90889SApple OSS Distributions assert3u(pub_data_size, <=, data_size);
187*43a90889SApple OSS Distributions assert3u(data_size, <, UINT16_MAX);
188*43a90889SApple OSS Distributions
189*43a90889SApple OSS Distributions lp->lp_stream = stream;
190*43a90889SApple OSS Distributions lp->lp_ftid = ftid;
191*43a90889SApple OSS Distributions lp->lp_timestamp = timestamp;
192*43a90889SApple OSS Distributions lp->lp_pub_data_size = (uint16_t)pub_data_size;
193*43a90889SApple OSS Distributions lp->lp_data_size = (uint16_t)data_size;
194*43a90889SApple OSS Distributions }
195*43a90889SApple OSS Distributions
196*43a90889SApple OSS Distributions static firehose_stream_t
firehose_stream(os_log_type_t type)197*43a90889SApple OSS Distributions firehose_stream(os_log_type_t type)
198*43a90889SApple OSS Distributions {
199*43a90889SApple OSS Distributions return (type == OS_LOG_TYPE_INFO || type == OS_LOG_TYPE_DEBUG) ?
200*43a90889SApple OSS Distributions firehose_stream_memory : firehose_stream_persist;
201*43a90889SApple OSS Distributions }
202*43a90889SApple OSS Distributions
203*43a90889SApple OSS Distributions static firehose_tracepoint_id_t
firehose_ftid(os_log_type_t type,const char * fmt,firehose_tracepoint_flags_t flags,void * dso,void * addr,bool driverKit)204*43a90889SApple OSS Distributions firehose_ftid(os_log_type_t type, const char *fmt, firehose_tracepoint_flags_t flags,
205*43a90889SApple OSS Distributions void *dso, void *addr, bool driverKit)
206*43a90889SApple OSS Distributions {
207*43a90889SApple OSS Distributions uint32_t off;
208*43a90889SApple OSS Distributions
209*43a90889SApple OSS Distributions if (driverKit) {
210*43a90889SApple OSS Distributions /*
211*43a90889SApple OSS Distributions * Set FIREHOSE_TRACEPOINT_PC_DYNAMIC_BIT so logd will not try
212*43a90889SApple OSS Distributions * to find the format string in the executable text.
213*43a90889SApple OSS Distributions */
214*43a90889SApple OSS Distributions off = (uint32_t)((uintptr_t)addr | FIREHOSE_TRACEPOINT_PC_DYNAMIC_BIT);
215*43a90889SApple OSS Distributions } else {
216*43a90889SApple OSS Distributions off = _os_trace_offset(dso, fmt, (_firehose_tracepoint_flags_activity_t)flags);
217*43a90889SApple OSS Distributions }
218*43a90889SApple OSS Distributions
219*43a90889SApple OSS Distributions return FIREHOSE_TRACE_ID_MAKE(firehose_tracepoint_namespace_log, type, flags, off);
220*43a90889SApple OSS Distributions }
221*43a90889SApple OSS Distributions
222*43a90889SApple OSS Distributions static firehose_tracepoint_flags_t
firehose_ftid_flags(const void * dso,bool driverKit)223*43a90889SApple OSS Distributions firehose_ftid_flags(const void *dso, bool driverKit)
224*43a90889SApple OSS Distributions {
225*43a90889SApple OSS Distributions kc_format_t kcformat = KCFormatUnknown;
226*43a90889SApple OSS Distributions __assert_only bool result = PE_get_primary_kc_format(&kcformat);
227*43a90889SApple OSS Distributions assert(result);
228*43a90889SApple OSS Distributions
229*43a90889SApple OSS Distributions if (kcformat == KCFormatStatic || kcformat == KCFormatKCGEN) {
230*43a90889SApple OSS Distributions return _firehose_tracepoint_flags_pc_style_shared_cache;
231*43a90889SApple OSS Distributions }
232*43a90889SApple OSS Distributions
233*43a90889SApple OSS Distributions /*
234*43a90889SApple OSS Distributions * driverKit will have the dso set as MH_EXECUTE (it is logging from a
235*43a90889SApple OSS Distributions * syscall in the kernel) but needs logd to parse the address as an
236*43a90889SApple OSS Distributions * absolute pc.
237*43a90889SApple OSS Distributions */
238*43a90889SApple OSS Distributions const kernel_mach_header_t *mh = dso;
239*43a90889SApple OSS Distributions if (mh->filetype == MH_EXECUTE && !driverKit) {
240*43a90889SApple OSS Distributions return _firehose_tracepoint_flags_pc_style_main_exe;
241*43a90889SApple OSS Distributions }
242*43a90889SApple OSS Distributions
243*43a90889SApple OSS Distributions return _firehose_tracepoint_flags_pc_style_absolute;
244*43a90889SApple OSS Distributions }
245*43a90889SApple OSS Distributions
246*43a90889SApple OSS Distributions static void *
resolve_dso(const char * fmt,void * dso,void * addr,bool driverKit)247*43a90889SApple OSS Distributions resolve_dso(const char *fmt, void *dso, void *addr, bool driverKit)
248*43a90889SApple OSS Distributions {
249*43a90889SApple OSS Distributions kc_format_t kcformat = KCFormatUnknown;
250*43a90889SApple OSS Distributions
251*43a90889SApple OSS Distributions if (!addr || !PE_get_primary_kc_format(&kcformat)) {
252*43a90889SApple OSS Distributions return NULL;
253*43a90889SApple OSS Distributions }
254*43a90889SApple OSS Distributions
255*43a90889SApple OSS Distributions switch (kcformat) {
256*43a90889SApple OSS Distributions case KCFormatStatic:
257*43a90889SApple OSS Distributions case KCFormatKCGEN:
258*43a90889SApple OSS Distributions dso = PE_get_kc_baseaddress(KCKindPrimary);
259*43a90889SApple OSS Distributions break;
260*43a90889SApple OSS Distributions case KCFormatDynamic:
261*43a90889SApple OSS Distributions case KCFormatFileset:
262*43a90889SApple OSS Distributions if (!dso && (dso = (void *)OSKextKextForAddress(fmt)) == NULL) {
263*43a90889SApple OSS Distributions return NULL;
264*43a90889SApple OSS Distributions }
265*43a90889SApple OSS Distributions if (!_os_trace_addr_in_text_segment(dso, fmt)) {
266*43a90889SApple OSS Distributions return NULL;
267*43a90889SApple OSS Distributions }
268*43a90889SApple OSS Distributions if (!driverKit && (dso != (void *)OSKextKextForAddress(addr))) {
269*43a90889SApple OSS Distributions return NULL;
270*43a90889SApple OSS Distributions }
271*43a90889SApple OSS Distributions break;
272*43a90889SApple OSS Distributions default:
273*43a90889SApple OSS Distributions panic("unknown KC format type");
274*43a90889SApple OSS Distributions }
275*43a90889SApple OSS Distributions
276*43a90889SApple OSS Distributions return dso;
277*43a90889SApple OSS Distributions }
278*43a90889SApple OSS Distributions
279*43a90889SApple OSS Distributions static inline uintptr_t
resolve_location(firehose_tracepoint_flags_t flags,uintptr_t dso,uintptr_t addr,bool driverKit,size_t * loc_size)280*43a90889SApple OSS Distributions resolve_location(firehose_tracepoint_flags_t flags, uintptr_t dso, uintptr_t addr,
281*43a90889SApple OSS Distributions bool driverKit, size_t *loc_size)
282*43a90889SApple OSS Distributions {
283*43a90889SApple OSS Distributions switch (flags & _firehose_tracepoint_flags_pc_style_mask) {
284*43a90889SApple OSS Distributions case _firehose_tracepoint_flags_pc_style_shared_cache:
285*43a90889SApple OSS Distributions case _firehose_tracepoint_flags_pc_style_main_exe:
286*43a90889SApple OSS Distributions *loc_size = sizeof(uint32_t);
287*43a90889SApple OSS Distributions return addr - dso;
288*43a90889SApple OSS Distributions case _firehose_tracepoint_flags_pc_style_absolute:
289*43a90889SApple OSS Distributions *loc_size = sizeof(uintptr_t);
290*43a90889SApple OSS Distributions return driverKit ? addr : VM_KERNEL_UNSLIDE(addr);
291*43a90889SApple OSS Distributions default:
292*43a90889SApple OSS Distributions panic("Unknown firehose tracepoint flags %x", flags);
293*43a90889SApple OSS Distributions }
294*43a90889SApple OSS Distributions }
295*43a90889SApple OSS Distributions
296*43a90889SApple OSS Distributions __startup_func
297*43a90889SApple OSS Distributions static void
oslog_init(void)298*43a90889SApple OSS Distributions oslog_init(void)
299*43a90889SApple OSS Distributions {
300*43a90889SApple OSS Distributions /*
301*43a90889SApple OSS Distributions * Disable kernel logging if ATM_TRACE_DISABLE set. ATM_TRACE_DISABLE
302*43a90889SApple OSS Distributions * bit is not supposed to change during a system run but nothing really
303*43a90889SApple OSS Distributions * prevents userspace from unintentionally doing so => we stash initial
304*43a90889SApple OSS Distributions * value in a dedicated variable for a later reference, just in case.
305*43a90889SApple OSS Distributions */
306*43a90889SApple OSS Distributions oslog_disabled = atm_get_diagnostic_config() & ATM_TRACE_DISABLE;
307*43a90889SApple OSS Distributions
308*43a90889SApple OSS Distributions if (!oslog_disabled) {
309*43a90889SApple OSS Distributions smr_hash_init(&os_log_cache, OS_LOG_SUBSYSTEM_MAX_CNT / 4);
310*43a90889SApple OSS Distributions }
311*43a90889SApple OSS Distributions }
312*43a90889SApple OSS Distributions STARTUP(OSLOG, STARTUP_RANK_FIRST, oslog_init);
313*43a90889SApple OSS Distributions
314*43a90889SApple OSS Distributions __startup_func
315*43a90889SApple OSS Distributions static void
oslog_init_logmem(void)316*43a90889SApple OSS Distributions oslog_init_logmem(void)
317*43a90889SApple OSS Distributions {
318*43a90889SApple OSS Distributions if (os_log_disabled()) {
319*43a90889SApple OSS Distributions printf("Long logs support disabled: Logging disabled by ATM\n");
320*43a90889SApple OSS Distributions return;
321*43a90889SApple OSS Distributions }
322*43a90889SApple OSS Distributions
323*43a90889SApple OSS Distributions const size_t logmem_size = logmem_required_size(OS_LOGMEM_BUF_ORDER, OS_LOGMEM_MIN_LOG_ORDER);
324*43a90889SApple OSS Distributions vm_offset_t addr;
325*43a90889SApple OSS Distributions
326*43a90889SApple OSS Distributions if (kmem_alloc(kernel_map, &addr, logmem_size + ptoa(2),
327*43a90889SApple OSS Distributions KMA_KOBJECT | KMA_PERMANENT | KMA_ZERO | KMA_GUARD_FIRST | KMA_GUARD_LAST,
328*43a90889SApple OSS Distributions VM_KERN_MEMORY_LOG) == KERN_SUCCESS) {
329*43a90889SApple OSS Distributions logmem_init(&os_log_mem, (void *)(addr + PAGE_SIZE), logmem_size,
330*43a90889SApple OSS Distributions OS_LOGMEM_BUF_ORDER, OS_LOGMEM_MIN_LOG_ORDER, OS_LOGMEM_MAX_LOG_ORDER);
331*43a90889SApple OSS Distributions printf("Long logs support configured: size: %u\n", os_log_mem.lm_cnt_free);
332*43a90889SApple OSS Distributions } else {
333*43a90889SApple OSS Distributions printf("Long logs support disabled: Not enough memory\n");
334*43a90889SApple OSS Distributions }
335*43a90889SApple OSS Distributions }
336*43a90889SApple OSS Distributions STARTUP(OSLOG, STARTUP_RANK_SECOND, oslog_init_logmem);
337*43a90889SApple OSS Distributions
338*43a90889SApple OSS Distributions bool
os_log_encoded_metadata(firehose_tracepoint_id_u ftid,uint64_t ts,const void * msg,size_t msg_size)339*43a90889SApple OSS Distributions os_log_encoded_metadata(firehose_tracepoint_id_u ftid, uint64_t ts, const void *msg,
340*43a90889SApple OSS Distributions size_t msg_size)
341*43a90889SApple OSS Distributions {
342*43a90889SApple OSS Distributions assert(ftid.ftid._namespace == firehose_tracepoint_namespace_metadata);
343*43a90889SApple OSS Distributions counter_inc(&oslog_p_total_msgcount);
344*43a90889SApple OSS Distributions
345*43a90889SApple OSS Distributions if (!os_log_safe() || os_log_disabled()) {
346*43a90889SApple OSS Distributions counter_inc(&oslog_p_metadata_dropped_msgcount);
347*43a90889SApple OSS Distributions return false;
348*43a90889SApple OSS Distributions }
349*43a90889SApple OSS Distributions
350*43a90889SApple OSS Distributions log_payload_s log;
351*43a90889SApple OSS Distributions log_payload_init(&log, firehose_stream_metadata, ftid, ts, msg_size, msg_size);
352*43a90889SApple OSS Distributions
353*43a90889SApple OSS Distributions if (log_queue_log(&log, msg, true)) {
354*43a90889SApple OSS Distributions return true;
355*43a90889SApple OSS Distributions }
356*43a90889SApple OSS Distributions
357*43a90889SApple OSS Distributions counter_inc(&oslog_p_metadata_dropped_msgcount);
358*43a90889SApple OSS Distributions return false;
359*43a90889SApple OSS Distributions }
360*43a90889SApple OSS Distributions
361*43a90889SApple OSS Distributions bool
os_log_encoded_log(firehose_stream_t stream,firehose_tracepoint_id_u ftid,uint64_t ts,const void * msg,size_t msg_size,size_t pub_data_size)362*43a90889SApple OSS Distributions os_log_encoded_log(firehose_stream_t stream, firehose_tracepoint_id_u ftid,
363*43a90889SApple OSS Distributions uint64_t ts, const void *msg, size_t msg_size, size_t pub_data_size)
364*43a90889SApple OSS Distributions {
365*43a90889SApple OSS Distributions assert(ftid.ftid._namespace == firehose_tracepoint_namespace_log);
366*43a90889SApple OSS Distributions counter_inc(&oslog_p_total_msgcount);
367*43a90889SApple OSS Distributions
368*43a90889SApple OSS Distributions if (!os_log_safe() || os_log_disabled()) {
369*43a90889SApple OSS Distributions counter_inc(&oslog_p_dropped_msgcount);
370*43a90889SApple OSS Distributions return false;
371*43a90889SApple OSS Distributions }
372*43a90889SApple OSS Distributions
373*43a90889SApple OSS Distributions log_payload_s log;
374*43a90889SApple OSS Distributions log_payload_init(&log, stream, ftid, ts, msg_size, pub_data_size);
375*43a90889SApple OSS Distributions
376*43a90889SApple OSS Distributions if (log_queue_log(&log, msg, true)) {
377*43a90889SApple OSS Distributions return true;
378*43a90889SApple OSS Distributions }
379*43a90889SApple OSS Distributions
380*43a90889SApple OSS Distributions counter_inc(&oslog_p_dropped_msgcount);
381*43a90889SApple OSS Distributions return false;
382*43a90889SApple OSS Distributions }
383*43a90889SApple OSS Distributions
384*43a90889SApple OSS Distributions bool
os_log_encoded_signpost(firehose_stream_t stream,firehose_tracepoint_id_u ftid,uint64_t ts,const void * msg,size_t msg_size,size_t pub_data_size)385*43a90889SApple OSS Distributions os_log_encoded_signpost(firehose_stream_t stream, firehose_tracepoint_id_u ftid,
386*43a90889SApple OSS Distributions uint64_t ts, const void *msg, size_t msg_size, size_t pub_data_size)
387*43a90889SApple OSS Distributions {
388*43a90889SApple OSS Distributions assert(ftid.ftid._namespace == firehose_tracepoint_namespace_signpost);
389*43a90889SApple OSS Distributions counter_inc(&oslog_p_total_msgcount);
390*43a90889SApple OSS Distributions
391*43a90889SApple OSS Distributions if (!os_log_safe() || os_log_disabled()) {
392*43a90889SApple OSS Distributions counter_inc(&oslog_p_signpost_dropped_msgcount);
393*43a90889SApple OSS Distributions return false;
394*43a90889SApple OSS Distributions }
395*43a90889SApple OSS Distributions
396*43a90889SApple OSS Distributions log_payload_s log;
397*43a90889SApple OSS Distributions log_payload_init(&log, stream, ftid, ts, msg_size, pub_data_size);
398*43a90889SApple OSS Distributions
399*43a90889SApple OSS Distributions if (log_queue_log(&log, msg, true)) {
400*43a90889SApple OSS Distributions return true;
401*43a90889SApple OSS Distributions }
402*43a90889SApple OSS Distributions
403*43a90889SApple OSS Distributions counter_inc(&oslog_p_signpost_dropped_msgcount);
404*43a90889SApple OSS Distributions return false;
405*43a90889SApple OSS Distributions }
406*43a90889SApple OSS Distributions
407*43a90889SApple OSS Distributions static inline size_t
os_log_subsystem_name_size(const char * name)408*43a90889SApple OSS Distributions os_log_subsystem_name_size(const char *name)
409*43a90889SApple OSS Distributions {
410*43a90889SApple OSS Distributions return MIN(strlen(name) + 1, OS_LOG_SUBSYSTEM_NAME_MAX_LEN);
411*43a90889SApple OSS Distributions }
412*43a90889SApple OSS Distributions
413*43a90889SApple OSS Distributions bool
os_log_subsystem_id_valid(uint16_t sid)414*43a90889SApple OSS Distributions os_log_subsystem_id_valid(uint16_t sid)
415*43a90889SApple OSS Distributions {
416*43a90889SApple OSS Distributions return sid >= OS_LOG_SUBSYSTEM_BASE && sid <= os_log_subsystem_id;
417*43a90889SApple OSS Distributions }
418*43a90889SApple OSS Distributions
419*43a90889SApple OSS Distributions static inline size_t
os_log_subsystem_id_length(const struct os_log_subsystem_s * sub)420*43a90889SApple OSS Distributions os_log_subsystem_id_length(const struct os_log_subsystem_s *sub)
421*43a90889SApple OSS Distributions {
422*43a90889SApple OSS Distributions return sub->ols_sub_size + sub->ols_cat_size;
423*43a90889SApple OSS Distributions }
424*43a90889SApple OSS Distributions
425*43a90889SApple OSS Distributions static inline size_t
os_log_subsystem_size(const struct os_log_subsystem_s * tbs)426*43a90889SApple OSS Distributions os_log_subsystem_size(const struct os_log_subsystem_s *tbs)
427*43a90889SApple OSS Distributions {
428*43a90889SApple OSS Distributions assert(tbs->ols_sub_size <= OS_LOG_SUBSYSTEM_NAME_MAX_LEN);
429*43a90889SApple OSS Distributions assert(tbs->ols_cat_size <= OS_LOG_SUBSYSTEM_NAME_MAX_LEN);
430*43a90889SApple OSS Distributions return sizeof(*tbs) - sizeof(tbs->ols_name) + os_log_subsystem_id_length(tbs);
431*43a90889SApple OSS Distributions }
432*43a90889SApple OSS Distributions
433*43a90889SApple OSS Distributions static void
os_log_subsystem_init(struct os_log_subsystem_s * ols,uint16_t sid,const char * sub,const char * cat)434*43a90889SApple OSS Distributions os_log_subsystem_init(struct os_log_subsystem_s *ols, uint16_t sid, const char *sub, const char *cat)
435*43a90889SApple OSS Distributions {
436*43a90889SApple OSS Distributions ols->ols_sub_size = os_log_subsystem_name_size(sub);
437*43a90889SApple OSS Distributions ols->ols_cat_size = os_log_subsystem_name_size(cat);
438*43a90889SApple OSS Distributions strlcpy(&ols->ols_name[0], sub, OS_LOG_SUBSYSTEM_NAME_MAX_LEN);
439*43a90889SApple OSS Distributions strlcpy(&ols->ols_name[ols->ols_sub_size], cat, OS_LOG_SUBSYSTEM_NAME_MAX_LEN);
440*43a90889SApple OSS Distributions ols->ols_id = sid;
441*43a90889SApple OSS Distributions }
442*43a90889SApple OSS Distributions
443*43a90889SApple OSS Distributions static void
os_log_subsystem_register(const struct os_log_subsystem_s * ols,uint64_t stamp)444*43a90889SApple OSS Distributions os_log_subsystem_register(const struct os_log_subsystem_s *ols, uint64_t stamp)
445*43a90889SApple OSS Distributions {
446*43a90889SApple OSS Distributions assert(os_log_subsystem_id_valid(ols->ols_id));
447*43a90889SApple OSS Distributions
448*43a90889SApple OSS Distributions firehose_tracepoint_id_u trace_id;
449*43a90889SApple OSS Distributions trace_id.ftid_value = FIREHOSE_TRACE_ID_MAKE(firehose_tracepoint_namespace_metadata,
450*43a90889SApple OSS Distributions _firehose_tracepoint_type_metadata_subsystem, 0, ols->ols_id);
451*43a90889SApple OSS Distributions
452*43a90889SApple OSS Distributions os_log_encoded_metadata(trace_id, stamp, ols, os_log_subsystem_size(ols));
453*43a90889SApple OSS Distributions }
454*43a90889SApple OSS Distributions
455*43a90889SApple OSS Distributions #if DEVELOPMENT || DEBUG
456*43a90889SApple OSS Distributions static bool
os_log_valid(const struct os_log_s * log)457*43a90889SApple OSS Distributions os_log_valid(const struct os_log_s *log)
458*43a90889SApple OSS Distributions {
459*43a90889SApple OSS Distributions return os_log_subsystem_id_valid(log->ol_subsystem.ols_id);
460*43a90889SApple OSS Distributions }
461*43a90889SApple OSS Distributions #endif // DEVELOPMENT || DEBUG
462*43a90889SApple OSS Distributions
463*43a90889SApple OSS Distributions static smrh_key_t
os_log_key(const struct os_log_subsystem_s * sub)464*43a90889SApple OSS Distributions os_log_key(const struct os_log_subsystem_s *sub)
465*43a90889SApple OSS Distributions {
466*43a90889SApple OSS Distributions return (smrh_key_t) {
467*43a90889SApple OSS Distributions .smrk_opaque = sub->ols_name,
468*43a90889SApple OSS Distributions .smrk_len = os_log_subsystem_id_length(sub)
469*43a90889SApple OSS Distributions };
470*43a90889SApple OSS Distributions }
471*43a90889SApple OSS Distributions
472*43a90889SApple OSS Distributions static uint32_t
os_log_key_hash(smrh_key_t key,uint32_t seed)473*43a90889SApple OSS Distributions os_log_key_hash(smrh_key_t key, uint32_t seed)
474*43a90889SApple OSS Distributions {
475*43a90889SApple OSS Distributions return smrh_key_hash_mem(key, seed);
476*43a90889SApple OSS Distributions }
477*43a90889SApple OSS Distributions
478*43a90889SApple OSS Distributions static bool
os_log_key_equ(smrh_key_t k1,smrh_key_t k2)479*43a90889SApple OSS Distributions os_log_key_equ(smrh_key_t k1, smrh_key_t k2)
480*43a90889SApple OSS Distributions {
481*43a90889SApple OSS Distributions return k1.smrk_len == k2.smrk_len ? smrh_key_equ_mem(k1, k2) : false;
482*43a90889SApple OSS Distributions }
483*43a90889SApple OSS Distributions
484*43a90889SApple OSS Distributions static uint32_t
os_log_hash(const struct smrq_slink * link,uint32_t seed)485*43a90889SApple OSS Distributions os_log_hash(const struct smrq_slink *link, uint32_t seed)
486*43a90889SApple OSS Distributions {
487*43a90889SApple OSS Distributions const os_log_t log = __container_of(link, struct os_log_s, ol_hash_link);
488*43a90889SApple OSS Distributions return os_log_key_hash(os_log_key(&log->ol_subsystem), seed);
489*43a90889SApple OSS Distributions }
490*43a90889SApple OSS Distributions
491*43a90889SApple OSS Distributions static bool
os_log_equ(const struct smrq_slink * link,smrh_key_t key)492*43a90889SApple OSS Distributions os_log_equ(const struct smrq_slink *link, smrh_key_t key)
493*43a90889SApple OSS Distributions {
494*43a90889SApple OSS Distributions const os_log_t h = __container_of(link, struct os_log_s, ol_hash_link);
495*43a90889SApple OSS Distributions return os_log_key_equ(os_log_key(&h->ol_subsystem), key);
496*43a90889SApple OSS Distributions }
497*43a90889SApple OSS Distributions
498*43a90889SApple OSS Distributions static bool
oslog_try_get(void * oslog __unused)499*43a90889SApple OSS Distributions oslog_try_get(void *oslog __unused)
500*43a90889SApple OSS Distributions {
501*43a90889SApple OSS Distributions return true;
502*43a90889SApple OSS Distributions }
503*43a90889SApple OSS Distributions
504*43a90889SApple OSS Distributions SMRH_TRAITS_DEFINE(os_log_cache_traits, struct os_log_s, ol_hash_link,
505*43a90889SApple OSS Distributions .domain = &smr_oslog,
506*43a90889SApple OSS Distributions .key_hash = os_log_key_hash,
507*43a90889SApple OSS Distributions .key_equ = os_log_key_equ,
508*43a90889SApple OSS Distributions .obj_hash = os_log_hash,
509*43a90889SApple OSS Distributions .obj_equ = os_log_equ,
510*43a90889SApple OSS Distributions .obj_try_get = oslog_try_get
511*43a90889SApple OSS Distributions );
512*43a90889SApple OSS Distributions
513*43a90889SApple OSS Distributions static os_log_t
os_log_cache_find_by_sub(const struct os_log_subsystem_s * sub)514*43a90889SApple OSS Distributions os_log_cache_find_by_sub(const struct os_log_subsystem_s *sub)
515*43a90889SApple OSS Distributions {
516*43a90889SApple OSS Distributions os_log_t log = smr_hash_get(&os_log_cache, os_log_key(sub), &os_log_cache_traits);
517*43a90889SApple OSS Distributions assert(!log || os_log_valid(log));
518*43a90889SApple OSS Distributions return log;
519*43a90889SApple OSS Distributions }
520*43a90889SApple OSS Distributions
521*43a90889SApple OSS Distributions static os_log_t
os_log_cache_insert(os_log_t log)522*43a90889SApple OSS Distributions os_log_cache_insert(os_log_t log)
523*43a90889SApple OSS Distributions {
524*43a90889SApple OSS Distributions assert(os_log_subsystem_id_valid(log->ol_subsystem.ols_id));
525*43a90889SApple OSS Distributions
526*43a90889SApple OSS Distributions os_log_t found = smr_hash_serialized_get_or_insert(&os_log_cache,
527*43a90889SApple OSS Distributions os_log_key(&log->ol_subsystem), &log->ol_hash_link,
528*43a90889SApple OSS Distributions &os_log_cache_traits);
529*43a90889SApple OSS Distributions assert(!found || os_log_valid(found));
530*43a90889SApple OSS Distributions return found;
531*43a90889SApple OSS Distributions }
532*43a90889SApple OSS Distributions
533*43a90889SApple OSS Distributions static os_log_t
os_log_allocate(const struct os_log_subsystem_s * subsystem)534*43a90889SApple OSS Distributions os_log_allocate(const struct os_log_subsystem_s *subsystem)
535*43a90889SApple OSS Distributions {
536*43a90889SApple OSS Distributions os_log_t new = kalloc_type(struct os_log_s, Z_WAITOK_ZERO);
537*43a90889SApple OSS Distributions if (new) {
538*43a90889SApple OSS Distributions new->ol_subsystem = *subsystem;
539*43a90889SApple OSS Distributions }
540*43a90889SApple OSS Distributions return new;
541*43a90889SApple OSS Distributions }
542*43a90889SApple OSS Distributions
543*43a90889SApple OSS Distributions static uint16_t
os_log_subsystem_id_next(void)544*43a90889SApple OSS Distributions os_log_subsystem_id_next(void)
545*43a90889SApple OSS Distributions {
546*43a90889SApple OSS Distributions assert(os_log_subsystem_id_valid(os_log_subsystem_id));
547*43a90889SApple OSS Distributions
548*43a90889SApple OSS Distributions if (__improbable(os_log_subsystem_id == OS_LOG_SUBSYSTEM_LAST)) {
549*43a90889SApple OSS Distributions return OS_LOG_SUBSYSTEM_NONE;
550*43a90889SApple OSS Distributions }
551*43a90889SApple OSS Distributions return os_log_subsystem_id++;
552*43a90889SApple OSS Distributions }
553*43a90889SApple OSS Distributions
554*43a90889SApple OSS Distributions static void
os_log_subsystem_id_revert(uint16_t __assert_only sid)555*43a90889SApple OSS Distributions os_log_subsystem_id_revert(uint16_t __assert_only sid)
556*43a90889SApple OSS Distributions {
557*43a90889SApple OSS Distributions assert(os_log_subsystem_id_valid(os_log_subsystem_id));
558*43a90889SApple OSS Distributions assert3u(os_log_subsystem_id, ==, sid + 1);
559*43a90889SApple OSS Distributions os_log_subsystem_id--;
560*43a90889SApple OSS Distributions }
561*43a90889SApple OSS Distributions
562*43a90889SApple OSS Distributions static os_log_t
os_log_create_impl(const char * subsystem,const char * category,uint64_t stamp)563*43a90889SApple OSS Distributions os_log_create_impl(const char *subsystem, const char *category, uint64_t stamp)
564*43a90889SApple OSS Distributions {
565*43a90889SApple OSS Distributions if (os_log_disabled()) {
566*43a90889SApple OSS Distributions return OS_LOG_DISABLED;
567*43a90889SApple OSS Distributions }
568*43a90889SApple OSS Distributions
569*43a90889SApple OSS Distributions struct os_log_subsystem_s new_sub;
570*43a90889SApple OSS Distributions os_log_subsystem_init(&new_sub, OS_LOG_SUBSYSTEM_NONE, subsystem, category);
571*43a90889SApple OSS Distributions
572*43a90889SApple OSS Distributions os_log_t log = os_log_cache_find_by_sub(&new_sub);
573*43a90889SApple OSS Distributions if (log) {
574*43a90889SApple OSS Distributions counter_inc(&oslog_subsystem_found);
575*43a90889SApple OSS Distributions return log;
576*43a90889SApple OSS Distributions }
577*43a90889SApple OSS Distributions
578*43a90889SApple OSS Distributions if (!(log = os_log_allocate(&new_sub))) {
579*43a90889SApple OSS Distributions counter_inc(&oslog_subsystem_dropped);
580*43a90889SApple OSS Distributions return OS_LOG_DEFAULT;
581*43a90889SApple OSS Distributions }
582*43a90889SApple OSS Distributions
583*43a90889SApple OSS Distributions lck_ticket_lock(&oslog_cache_lock, &oslog_cache_lock_grp);
584*43a90889SApple OSS Distributions
585*43a90889SApple OSS Distributions log->ol_subsystem.ols_id = os_log_subsystem_id_next();
586*43a90889SApple OSS Distributions if (__improbable(log->ol_subsystem.ols_id == OS_LOG_SUBSYSTEM_NONE)) {
587*43a90889SApple OSS Distributions lck_ticket_unlock(&oslog_cache_lock);
588*43a90889SApple OSS Distributions kfree_type(struct os_log_s, log);
589*43a90889SApple OSS Distributions counter_inc(&oslog_subsystem_dropped);
590*43a90889SApple OSS Distributions return OS_LOG_DEFAULT;
591*43a90889SApple OSS Distributions }
592*43a90889SApple OSS Distributions
593*43a90889SApple OSS Distributions os_log_t found = os_log_cache_insert(log);
594*43a90889SApple OSS Distributions if (__improbable(found)) {
595*43a90889SApple OSS Distributions os_log_subsystem_id_revert(log->ol_subsystem.ols_id);
596*43a90889SApple OSS Distributions lck_ticket_unlock(&oslog_cache_lock);
597*43a90889SApple OSS Distributions kfree_type(struct os_log_s, log);
598*43a90889SApple OSS Distributions counter_inc(&oslog_subsystem_found);
599*43a90889SApple OSS Distributions return found;
600*43a90889SApple OSS Distributions }
601*43a90889SApple OSS Distributions
602*43a90889SApple OSS Distributions lck_ticket_unlock(&oslog_cache_lock);
603*43a90889SApple OSS Distributions
604*43a90889SApple OSS Distributions os_log_subsystem_register(&log->ol_subsystem, stamp);
605*43a90889SApple OSS Distributions counter_inc(&oslog_subsystem_count);
606*43a90889SApple OSS Distributions
607*43a90889SApple OSS Distributions return log;
608*43a90889SApple OSS Distributions }
609*43a90889SApple OSS Distributions
610*43a90889SApple OSS Distributions os_log_t
os_log_create(const char * subsystem,const char * category)611*43a90889SApple OSS Distributions os_log_create(const char *subsystem, const char *category)
612*43a90889SApple OSS Distributions {
613*43a90889SApple OSS Distributions uint64_t stamp = firehose_tracepoint_time(firehose_activity_flags_default);
614*43a90889SApple OSS Distributions return os_log_create_impl(subsystem, category, stamp);
615*43a90889SApple OSS Distributions }
616*43a90889SApple OSS Distributions
617*43a90889SApple OSS Distributions static void
_os_log_to_msgbuf_internal(const char * format,va_list args,uint64_t timestamp,bool safe,bool logging,bool addcr)618*43a90889SApple OSS Distributions _os_log_to_msgbuf_internal(const char *format, va_list args, uint64_t timestamp,
619*43a90889SApple OSS Distributions bool safe, bool logging, bool addcr)
620*43a90889SApple OSS Distributions {
621*43a90889SApple OSS Distributions /*
622*43a90889SApple OSS Distributions * The following threshold was determined empirically as the point where
623*43a90889SApple OSS Distributions * it would be more advantageous to be able to fit in more log lines than
624*43a90889SApple OSS Distributions * to know exactly when a log line was printed out. We don't want to use up
625*43a90889SApple OSS Distributions * a large percentage of the log buffer on timestamps in a memory-constricted
626*43a90889SApple OSS Distributions * environment.
627*43a90889SApple OSS Distributions */
628*43a90889SApple OSS Distributions const int MSGBUF_TIMESTAMP_THRESHOLD = 4096;
629*43a90889SApple OSS Distributions static int msgbufreplay = -1;
630*43a90889SApple OSS Distributions static bool newlogline = true;
631*43a90889SApple OSS Distributions va_list args_copy;
632*43a90889SApple OSS Distributions
633*43a90889SApple OSS Distributions if (!bsd_log_lock(safe)) {
634*43a90889SApple OSS Distributions counter_inc(&oslog_msgbuf_dropped_msgcount);
635*43a90889SApple OSS Distributions return;
636*43a90889SApple OSS Distributions }
637*43a90889SApple OSS Distributions
638*43a90889SApple OSS Distributions if (!safe) {
639*43a90889SApple OSS Distributions if (-1 == msgbufreplay) {
640*43a90889SApple OSS Distributions msgbufreplay = msgbufp->msg_bufx;
641*43a90889SApple OSS Distributions }
642*43a90889SApple OSS Distributions } else if (logging && (-1 != msgbufreplay)) {
643*43a90889SApple OSS Distributions uint32_t i;
644*43a90889SApple OSS Distributions uint32_t localbuff_size;
645*43a90889SApple OSS Distributions int newl, position;
646*43a90889SApple OSS Distributions char *localbuff, *p, *s, *next, ch;
647*43a90889SApple OSS Distributions
648*43a90889SApple OSS Distributions position = msgbufreplay;
649*43a90889SApple OSS Distributions msgbufreplay = -1;
650*43a90889SApple OSS Distributions localbuff_size = (msgbufp->msg_size + 2); /* + '\n' + '\0' */
651*43a90889SApple OSS Distributions /* Size for non-blocking */
652*43a90889SApple OSS Distributions if (localbuff_size > 4096) {
653*43a90889SApple OSS Distributions localbuff_size = 4096;
654*43a90889SApple OSS Distributions }
655*43a90889SApple OSS Distributions bsd_log_unlock();
656*43a90889SApple OSS Distributions /* Allocate a temporary non-circular buffer */
657*43a90889SApple OSS Distributions localbuff = kalloc_data(localbuff_size, Z_NOWAIT);
658*43a90889SApple OSS Distributions if (localbuff != NULL) {
659*43a90889SApple OSS Distributions /* in between here, the log could become bigger, but that's fine */
660*43a90889SApple OSS Distributions bsd_log_lock(true);
661*43a90889SApple OSS Distributions /*
662*43a90889SApple OSS Distributions * The message buffer is circular; start at the replay pointer, and
663*43a90889SApple OSS Distributions * make one loop up to write pointer - 1.
664*43a90889SApple OSS Distributions */
665*43a90889SApple OSS Distributions p = msgbufp->msg_bufc + position;
666*43a90889SApple OSS Distributions for (i = newl = 0; p != msgbufp->msg_bufc + msgbufp->msg_bufx - 1; ++p) {
667*43a90889SApple OSS Distributions if (p >= msgbufp->msg_bufc + msgbufp->msg_size) {
668*43a90889SApple OSS Distributions p = msgbufp->msg_bufc;
669*43a90889SApple OSS Distributions }
670*43a90889SApple OSS Distributions ch = *p;
671*43a90889SApple OSS Distributions if (ch == '\0') {
672*43a90889SApple OSS Distributions continue;
673*43a90889SApple OSS Distributions }
674*43a90889SApple OSS Distributions newl = (ch == '\n');
675*43a90889SApple OSS Distributions localbuff[i++] = ch;
676*43a90889SApple OSS Distributions if (i >= (localbuff_size - 2)) {
677*43a90889SApple OSS Distributions break;
678*43a90889SApple OSS Distributions }
679*43a90889SApple OSS Distributions }
680*43a90889SApple OSS Distributions bsd_log_unlock();
681*43a90889SApple OSS Distributions
682*43a90889SApple OSS Distributions if (!newl) {
683*43a90889SApple OSS Distributions localbuff[i++] = '\n';
684*43a90889SApple OSS Distributions }
685*43a90889SApple OSS Distributions localbuff[i++] = 0;
686*43a90889SApple OSS Distributions
687*43a90889SApple OSS Distributions s = localbuff;
688*43a90889SApple OSS Distributions while ((next = strchr(s, '\n'))) {
689*43a90889SApple OSS Distributions next++;
690*43a90889SApple OSS Distributions ch = next[0];
691*43a90889SApple OSS Distributions next[0] = 0;
692*43a90889SApple OSS Distributions os_log(&_os_log_replay, "%s", s);
693*43a90889SApple OSS Distributions next[0] = ch;
694*43a90889SApple OSS Distributions s = next;
695*43a90889SApple OSS Distributions }
696*43a90889SApple OSS Distributions kfree_data(localbuff, localbuff_size);
697*43a90889SApple OSS Distributions }
698*43a90889SApple OSS Distributions bsd_log_lock(true);
699*43a90889SApple OSS Distributions }
700*43a90889SApple OSS Distributions
701*43a90889SApple OSS Distributions /* Do not prepend timestamps when we are memory-constricted */
702*43a90889SApple OSS Distributions if (newlogline && (msgbufp->msg_size > MSGBUF_TIMESTAMP_THRESHOLD)) {
703*43a90889SApple OSS Distributions clock_sec_t secs;
704*43a90889SApple OSS Distributions clock_usec_t microsecs;
705*43a90889SApple OSS Distributions absolutetime_to_microtime(timestamp, &secs, µsecs);
706*43a90889SApple OSS Distributions printf_log_locked(FALSE, "[%5lu.%06u]: ", (unsigned long)secs, microsecs);
707*43a90889SApple OSS Distributions }
708*43a90889SApple OSS Distributions
709*43a90889SApple OSS Distributions #pragma clang diagnostic push
710*43a90889SApple OSS Distributions #pragma clang diagnostic ignored "-Wformat-nonliteral"
711*43a90889SApple OSS Distributions va_copy(args_copy, args);
712*43a90889SApple OSS Distributions newlogline = vprintf_log_locked(format, args_copy, addcr);
713*43a90889SApple OSS Distributions va_end(args_copy);
714*43a90889SApple OSS Distributions #pragma clang diagnostic pop
715*43a90889SApple OSS Distributions
716*43a90889SApple OSS Distributions bsd_log_unlock();
717*43a90889SApple OSS Distributions logwakeup();
718*43a90889SApple OSS Distributions counter_inc(&oslog_msgbuf_msgcount);
719*43a90889SApple OSS Distributions }
720*43a90889SApple OSS Distributions
721*43a90889SApple OSS Distributions static void
_os_log_to_log_internal(uint16_t sid,os_log_type_t type,const char * fmt,va_list args,uint64_t ts,void * addr,void * dso,bool driverKit)722*43a90889SApple OSS Distributions _os_log_to_log_internal(uint16_t sid, os_log_type_t type, const char *fmt, va_list args,
723*43a90889SApple OSS Distributions uint64_t ts, void *addr, void *dso, bool driverKit)
724*43a90889SApple OSS Distributions {
725*43a90889SApple OSS Distributions dso = resolve_dso(fmt, dso, addr, driverKit);
726*43a90889SApple OSS Distributions if (__improbable(!dso)) {
727*43a90889SApple OSS Distributions counter_inc(&oslog_p_unresolved_kc_msgcount);
728*43a90889SApple OSS Distributions return;
729*43a90889SApple OSS Distributions }
730*43a90889SApple OSS Distributions
731*43a90889SApple OSS Distributions firehose_tracepoint_flags_t flags = firehose_ftid_flags(dso, driverKit);
732*43a90889SApple OSS Distributions if (sid != 0) {
733*43a90889SApple OSS Distributions flags |= _firehose_tracepoint_flags_log_has_subsystem;
734*43a90889SApple OSS Distributions }
735*43a90889SApple OSS Distributions
736*43a90889SApple OSS Distributions size_t loc_sz = 0;
737*43a90889SApple OSS Distributions uintptr_t loc = resolve_location(flags, (uintptr_t)dso, (uintptr_t)addr,
738*43a90889SApple OSS Distributions driverKit, &loc_sz);
739*43a90889SApple OSS Distributions
740*43a90889SApple OSS Distributions firehose_tracepoint_id_u ftid = {
741*43a90889SApple OSS Distributions .ftid_value = firehose_ftid(type, fmt, flags, dso, addr, driverKit)
742*43a90889SApple OSS Distributions };
743*43a90889SApple OSS Distributions
744*43a90889SApple OSS Distributions __attribute__((uninitialized, aligned(8)))
745*43a90889SApple OSS Distributions uint8_t buffer[OS_LOG_BUFFER_MAX_SIZE];
746*43a90889SApple OSS Distributions struct os_log_context_s ctx;
747*43a90889SApple OSS Distributions
748*43a90889SApple OSS Distributions os_log_context_init(&ctx, &os_log_mem, buffer, sizeof(buffer));
749*43a90889SApple OSS Distributions
750*43a90889SApple OSS Distributions if (!os_log_context_encode(&ctx, fmt, args, loc, loc_sz, sid)) {
751*43a90889SApple OSS Distributions counter_inc(&oslog_p_error_count);
752*43a90889SApple OSS Distributions os_log_context_free(&ctx);
753*43a90889SApple OSS Distributions return;
754*43a90889SApple OSS Distributions }
755*43a90889SApple OSS Distributions
756*43a90889SApple OSS Distributions log_payload_s log;
757*43a90889SApple OSS Distributions log_payload_init(&log, firehose_stream(type), ftid, ts, ctx.ctx_content_sz, ctx.ctx_content_sz);
758*43a90889SApple OSS Distributions
759*43a90889SApple OSS Distributions if (!log_queue_log(&log, ctx.ctx_buffer, true)) {
760*43a90889SApple OSS Distributions counter_inc(&oslog_p_dropped_msgcount);
761*43a90889SApple OSS Distributions }
762*43a90889SApple OSS Distributions
763*43a90889SApple OSS Distributions os_log_context_free(&ctx);
764*43a90889SApple OSS Distributions }
765*43a90889SApple OSS Distributions
766*43a90889SApple OSS Distributions static void
_os_log_with_args_internal(os_log_t oslog,os_log_type_t type,const char * fmt,va_list args,uint64_t ts,void * addr,void * dso,bool driverKit,bool addcr)767*43a90889SApple OSS Distributions _os_log_with_args_internal(os_log_t oslog, os_log_type_t type, const char *fmt,
768*43a90889SApple OSS Distributions va_list args, uint64_t ts, void *addr, void *dso, bool driverKit, bool addcr)
769*43a90889SApple OSS Distributions {
770*43a90889SApple OSS Distributions counter_inc(&oslog_p_total_msgcount);
771*43a90889SApple OSS Distributions
772*43a90889SApple OSS Distributions if (oslog == OS_LOG_DISABLED) {
773*43a90889SApple OSS Distributions counter_inc(&oslog_p_dropped_msgcount);
774*43a90889SApple OSS Distributions return;
775*43a90889SApple OSS Distributions }
776*43a90889SApple OSS Distributions
777*43a90889SApple OSS Distributions if (__improbable(fmt[0] == '\0')) {
778*43a90889SApple OSS Distributions counter_inc(&oslog_p_error_count);
779*43a90889SApple OSS Distributions return;
780*43a90889SApple OSS Distributions }
781*43a90889SApple OSS Distributions
782*43a90889SApple OSS Distributions /* early boot can log to dmesg for later replay (27307943) */
783*43a90889SApple OSS Distributions bool safe = os_log_safe();
784*43a90889SApple OSS Distributions bool logging = !os_log_turned_off();
785*43a90889SApple OSS Distributions
786*43a90889SApple OSS Distributions if (oslog != &_os_log_replay) {
787*43a90889SApple OSS Distributions _os_log_to_msgbuf_internal(fmt, args, ts, safe, logging, addcr);
788*43a90889SApple OSS Distributions }
789*43a90889SApple OSS Distributions
790*43a90889SApple OSS Distributions if (safe && logging) {
791*43a90889SApple OSS Distributions const uint16_t sid = oslog->ol_subsystem.ols_id;
792*43a90889SApple OSS Distributions _os_log_to_log_internal(sid, type, fmt, args, ts, addr, dso, driverKit);
793*43a90889SApple OSS Distributions }
794*43a90889SApple OSS Distributions }
795*43a90889SApple OSS Distributions
796*43a90889SApple OSS Distributions __attribute__((noinline, not_tail_called)) void
_os_log_internal(void * dso,os_log_t log,uint8_t type,const char * fmt,...)797*43a90889SApple OSS Distributions _os_log_internal(void *dso, os_log_t log, uint8_t type, const char *fmt, ...)
798*43a90889SApple OSS Distributions {
799*43a90889SApple OSS Distributions uint64_t ts = firehose_tracepoint_time(firehose_activity_flags_default);
800*43a90889SApple OSS Distributions void *addr = __builtin_return_address(0);
801*43a90889SApple OSS Distributions va_list args;
802*43a90889SApple OSS Distributions
803*43a90889SApple OSS Distributions va_start(args, fmt);
804*43a90889SApple OSS Distributions _os_log_with_args_internal(log, type, fmt, args, ts, addr, dso, FALSE, FALSE);
805*43a90889SApple OSS Distributions va_end(args);
806*43a90889SApple OSS Distributions }
807*43a90889SApple OSS Distributions
808*43a90889SApple OSS Distributions __attribute__((noinline, not_tail_called)) void
_os_log_at_time(void * dso,os_log_t log,uint8_t type,uint64_t ts,const char * fmt,...)809*43a90889SApple OSS Distributions _os_log_at_time(void *dso, os_log_t log, uint8_t type, uint64_t ts, const char *fmt, ...)
810*43a90889SApple OSS Distributions {
811*43a90889SApple OSS Distributions void *addr = __builtin_return_address(0);
812*43a90889SApple OSS Distributions va_list args;
813*43a90889SApple OSS Distributions
814*43a90889SApple OSS Distributions va_start(args, fmt);
815*43a90889SApple OSS Distributions _os_log_with_args_internal(log, type, fmt, args, ts, addr, dso, FALSE, FALSE);
816*43a90889SApple OSS Distributions va_end(args);
817*43a90889SApple OSS Distributions }
818*43a90889SApple OSS Distributions
819*43a90889SApple OSS Distributions __attribute__((noinline, not_tail_called)) int
_os_log_internal_driverKit(void * dso,os_log_t log,uint8_t type,const char * fmt,...)820*43a90889SApple OSS Distributions _os_log_internal_driverKit(void *dso, os_log_t log, uint8_t type, const char *fmt, ...)
821*43a90889SApple OSS Distributions {
822*43a90889SApple OSS Distributions uint64_t ts = firehose_tracepoint_time(firehose_activity_flags_default);
823*43a90889SApple OSS Distributions void *addr = __builtin_return_address(0);
824*43a90889SApple OSS Distributions bool driverKitLog = FALSE;
825*43a90889SApple OSS Distributions va_list args;
826*43a90889SApple OSS Distributions
827*43a90889SApple OSS Distributions /*
828*43a90889SApple OSS Distributions * We want to be able to identify dexts from the logs.
829*43a90889SApple OSS Distributions *
830*43a90889SApple OSS Distributions * Usually the addr is used to understand if the log line
831*43a90889SApple OSS Distributions * was generated by a kext or the kernel main executable.
832*43a90889SApple OSS Distributions * Logd uses copyKextUUIDForAddress with the addr specified
833*43a90889SApple OSS Distributions * in the log line to retrieve the kext UUID of the sender.
834*43a90889SApple OSS Distributions *
835*43a90889SApple OSS Distributions * Dext however are not loaded in kernel space so they do not
836*43a90889SApple OSS Distributions * have a kernel range of addresses.
837*43a90889SApple OSS Distributions *
838*43a90889SApple OSS Distributions * To make the same mechanism work, OSKext fakes a kernel
839*43a90889SApple OSS Distributions * address range for dexts using the loadTag,
840*43a90889SApple OSS Distributions * so we just need to use the loadTag as addr here
841*43a90889SApple OSS Distributions * to allow logd to retrieve the correct UUID.
842*43a90889SApple OSS Distributions *
843*43a90889SApple OSS Distributions * NOTE: loadTag is populated in the task when the dext is matching,
844*43a90889SApple OSS Distributions * so if log lines are generated before the matching they will be
845*43a90889SApple OSS Distributions * identified as kernel main executable.
846*43a90889SApple OSS Distributions */
847*43a90889SApple OSS Distributions task_t self_task = current_task();
848*43a90889SApple OSS Distributions
849*43a90889SApple OSS Distributions /*
850*43a90889SApple OSS Distributions * Only dexts are supposed to use this log path. Verified in log_data()
851*43a90889SApple OSS Distributions * but worth of another check here in case this function gets called
852*43a90889SApple OSS Distributions * directly.
853*43a90889SApple OSS Distributions */
854*43a90889SApple OSS Distributions if (!task_is_driver(self_task)) {
855*43a90889SApple OSS Distributions return EPERM;
856*43a90889SApple OSS Distributions }
857*43a90889SApple OSS Distributions
858*43a90889SApple OSS Distributions uint64_t loadTag = get_task_loadTag(self_task);
859*43a90889SApple OSS Distributions if (loadTag != 0) {
860*43a90889SApple OSS Distributions driverKitLog = TRUE;
861*43a90889SApple OSS Distributions addr = (void *)loadTag;
862*43a90889SApple OSS Distributions }
863*43a90889SApple OSS Distributions
864*43a90889SApple OSS Distributions va_start(args, fmt);
865*43a90889SApple OSS Distributions _os_log_with_args_internal(log, type, fmt, args, ts, addr, dso, driverKitLog, true);
866*43a90889SApple OSS Distributions va_end(args);
867*43a90889SApple OSS Distributions
868*43a90889SApple OSS Distributions return 0;
869*43a90889SApple OSS Distributions }
870*43a90889SApple OSS Distributions
871*43a90889SApple OSS Distributions __attribute__((noinline, not_tail_called)) void
os_log_with_args(os_log_t oslog,os_log_type_t type,const char * fmt,va_list args,void * addr)872*43a90889SApple OSS Distributions os_log_with_args(os_log_t oslog, os_log_type_t type, const char *fmt,
873*43a90889SApple OSS Distributions va_list args, void *addr)
874*43a90889SApple OSS Distributions {
875*43a90889SApple OSS Distributions uint64_t ts = firehose_tracepoint_time(firehose_activity_flags_default);
876*43a90889SApple OSS Distributions
877*43a90889SApple OSS Distributions // if no address passed, look it up
878*43a90889SApple OSS Distributions if (addr == NULL) {
879*43a90889SApple OSS Distributions addr = __builtin_return_address(0);
880*43a90889SApple OSS Distributions }
881*43a90889SApple OSS Distributions
882*43a90889SApple OSS Distributions _os_log_with_args_internal(oslog, type, fmt, args, ts, addr, NULL, FALSE, FALSE);
883*43a90889SApple OSS Distributions }
884*43a90889SApple OSS Distributions
885*43a90889SApple OSS Distributions bool
os_log_coprocessor(void * buff,uint64_t buff_len,os_log_type_t type,const char * uuid,uint64_t timestamp,uint32_t offset,bool stream_log)886*43a90889SApple OSS Distributions os_log_coprocessor(void *buff, uint64_t buff_len, os_log_type_t type,
887*43a90889SApple OSS Distributions const char *uuid, uint64_t timestamp, uint32_t offset, bool stream_log)
888*43a90889SApple OSS Distributions {
889*43a90889SApple OSS Distributions counter_inc(&oslog_p_coprocessor_total_msgcount);
890*43a90889SApple OSS Distributions
891*43a90889SApple OSS Distributions if (os_log_turned_off() || !os_log_safe()) {
892*43a90889SApple OSS Distributions counter_inc(&oslog_p_coprocessor_dropped_msgcount);
893*43a90889SApple OSS Distributions return false;
894*43a90889SApple OSS Distributions }
895*43a90889SApple OSS Distributions
896*43a90889SApple OSS Distributions if (buff_len + 16 + sizeof(uint32_t) > OS_LOG_BUFFER_MAX_SIZE) {
897*43a90889SApple OSS Distributions counter_inc(&oslog_p_coprocessor_dropped_msgcount);
898*43a90889SApple OSS Distributions return false;
899*43a90889SApple OSS Distributions }
900*43a90889SApple OSS Distributions
901*43a90889SApple OSS Distributions __attribute__((uninitialized))
902*43a90889SApple OSS Distributions uint8_t pubdata[OS_LOG_BUFFER_MAX_SIZE];
903*43a90889SApple OSS Distributions size_t wr_pos = 0;
904*43a90889SApple OSS Distributions
905*43a90889SApple OSS Distributions memcpy(pubdata, &offset, sizeof(uint32_t));
906*43a90889SApple OSS Distributions wr_pos += sizeof(uint32_t);
907*43a90889SApple OSS Distributions memcpy(pubdata + wr_pos, uuid, 16);
908*43a90889SApple OSS Distributions wr_pos += 16;
909*43a90889SApple OSS Distributions
910*43a90889SApple OSS Distributions memcpy(pubdata + wr_pos, buff, buff_len);
911*43a90889SApple OSS Distributions wr_pos += buff_len;
912*43a90889SApple OSS Distributions
913*43a90889SApple OSS Distributions /*
914*43a90889SApple OSS Distributions * Unlike KEXTs, where PC is used to find UUID, in coprocessor logs the UUID
915*43a90889SApple OSS Distributions * is passed as part of the tracepoint.
916*43a90889SApple OSS Distributions */
917*43a90889SApple OSS Distributions firehose_tracepoint_namespace_t ns = firehose_tracepoint_namespace_log;
918*43a90889SApple OSS Distributions firehose_tracepoint_flags_t flags = _firehose_tracepoint_flags_pc_style_uuid_relative;
919*43a90889SApple OSS Distributions firehose_tracepoint_id_u trace_id = {
920*43a90889SApple OSS Distributions .ftid_value = FIREHOSE_TRACE_ID_MAKE(ns, type, flags, offset)
921*43a90889SApple OSS Distributions };
922*43a90889SApple OSS Distributions
923*43a90889SApple OSS Distributions log_payload_s log;
924*43a90889SApple OSS Distributions log_payload_init(&log, firehose_stream(type), trace_id, timestamp, wr_pos, wr_pos);
925*43a90889SApple OSS Distributions
926*43a90889SApple OSS Distributions if (!log_queue_log(&log, pubdata, stream_log)) {
927*43a90889SApple OSS Distributions counter_inc(&oslog_p_coprocessor_dropped_msgcount);
928*43a90889SApple OSS Distributions return false;
929*43a90889SApple OSS Distributions }
930*43a90889SApple OSS Distributions
931*43a90889SApple OSS Distributions return true;
932*43a90889SApple OSS Distributions }
933*43a90889SApple OSS Distributions
934*43a90889SApple OSS Distributions static inline firehose_tracepoint_t
firehose_trace_start(const log_payload_s * lp,uint8_t ** ft_priv_data)935*43a90889SApple OSS Distributions firehose_trace_start(const log_payload_s *lp, uint8_t **ft_priv_data)
936*43a90889SApple OSS Distributions {
937*43a90889SApple OSS Distributions uint16_t priv_data_size = (uint16_t)log_payload_priv_data_size(lp);
938*43a90889SApple OSS Distributions uint16_t pub_data_size = (uint16_t)lp->lp_pub_data_size;
939*43a90889SApple OSS Distributions
940*43a90889SApple OSS Distributions if (priv_data_size > 0) {
941*43a90889SApple OSS Distributions pub_data_size += sizeof(struct firehose_buffer_range_s);
942*43a90889SApple OSS Distributions }
943*43a90889SApple OSS Distributions
944*43a90889SApple OSS Distributions assert3u(offsetof(struct firehose_tracepoint_s, ft_data) +
945*43a90889SApple OSS Distributions pub_data_size + priv_data_size, <=, sizeof(((firehose_chunk_t)0)->fc_data));
946*43a90889SApple OSS Distributions
947*43a90889SApple OSS Distributions firehose_tracepoint_t ft = __firehose_buffer_tracepoint_reserve(lp->lp_timestamp,
948*43a90889SApple OSS Distributions lp->lp_stream, pub_data_size, priv_data_size, ft_priv_data);
949*43a90889SApple OSS Distributions
950*43a90889SApple OSS Distributions if (fastpath(ft)) {
951*43a90889SApple OSS Distributions oslog_boot_done = true;
952*43a90889SApple OSS Distributions return ft;
953*43a90889SApple OSS Distributions }
954*43a90889SApple OSS Distributions
955*43a90889SApple OSS Distributions if (fastpath(oslog_boot_done)) {
956*43a90889SApple OSS Distributions return 0;
957*43a90889SApple OSS Distributions }
958*43a90889SApple OSS Distributions
959*43a90889SApple OSS Distributions /*
960*43a90889SApple OSS Distributions * Early boot logging when kernel logging is up and running but logd is
961*43a90889SApple OSS Distributions * not yet ready. Only the persist firehose stream is available.
962*43a90889SApple OSS Distributions */
963*43a90889SApple OSS Distributions
964*43a90889SApple OSS Distributions long offset = firehose_chunk_tracepoint_try_reserve(&firehose_boot_chunk,
965*43a90889SApple OSS Distributions lp->lp_timestamp, firehose_stream_persist, 0, pub_data_size,
966*43a90889SApple OSS Distributions priv_data_size, ft_priv_data);
967*43a90889SApple OSS Distributions if (offset <= 0) {
968*43a90889SApple OSS Distributions counter_inc(&oslog_p_boot_dropped_msgcount);
969*43a90889SApple OSS Distributions return 0;
970*43a90889SApple OSS Distributions }
971*43a90889SApple OSS Distributions
972*43a90889SApple OSS Distributions return firehose_chunk_tracepoint_begin(&firehose_boot_chunk,
973*43a90889SApple OSS Distributions lp->lp_timestamp, pub_data_size, thread_tid(current_thread()),
974*43a90889SApple OSS Distributions offset);
975*43a90889SApple OSS Distributions }
976*43a90889SApple OSS Distributions
977*43a90889SApple OSS Distributions static inline void
firehose_trace_finish(firehose_tracepoint_t ft,firehose_tracepoint_id_u ftid)978*43a90889SApple OSS Distributions firehose_trace_finish(firehose_tracepoint_t ft, firehose_tracepoint_id_u ftid)
979*43a90889SApple OSS Distributions {
980*43a90889SApple OSS Distributions if (__probable(oslog_boot_done)) {
981*43a90889SApple OSS Distributions __firehose_buffer_tracepoint_flush(ft, ftid);
982*43a90889SApple OSS Distributions } else {
983*43a90889SApple OSS Distributions firehose_chunk_tracepoint_end(&firehose_boot_chunk, ft, ftid);
984*43a90889SApple OSS Distributions }
985*43a90889SApple OSS Distributions }
986*43a90889SApple OSS Distributions
987*43a90889SApple OSS Distributions static inline void
firehose_trace_save_payload(const log_payload_s * lp,const uint8_t * lp_data,firehose_tracepoint_t ft,uint8_t * ft_priv_data)988*43a90889SApple OSS Distributions firehose_trace_save_payload(const log_payload_s *lp, const uint8_t *lp_data,
989*43a90889SApple OSS Distributions firehose_tracepoint_t ft, uint8_t *ft_priv_data)
990*43a90889SApple OSS Distributions {
991*43a90889SApple OSS Distributions const size_t priv_data_size = log_payload_priv_data_size(lp);
992*43a90889SApple OSS Distributions uint8_t *ft_data = ft->ft_data;
993*43a90889SApple OSS Distributions
994*43a90889SApple OSS Distributions if (priv_data_size > 0) {
995*43a90889SApple OSS Distributions assert(FIREHOSE_TRACE_ID_HAS_FLAG(lp->lp_ftid, log, has_private_data));
996*43a90889SApple OSS Distributions memcpy(ft_priv_data, log_payload_priv_data(lp, lp_data), priv_data_size);
997*43a90889SApple OSS Distributions
998*43a90889SApple OSS Distributions firehose_chunk_t fc = firehose_chunk_for_address(ft);
999*43a90889SApple OSS Distributions struct firehose_buffer_range_s range = {
1000*43a90889SApple OSS Distributions .fbr_offset = (uint16_t)(ft_priv_data - fc->fc_start),
1001*43a90889SApple OSS Distributions .fbr_length = (uint16_t)priv_data_size
1002*43a90889SApple OSS Distributions };
1003*43a90889SApple OSS Distributions memcpy(ft_data, &range, sizeof(range));
1004*43a90889SApple OSS Distributions ft_data += sizeof(range);
1005*43a90889SApple OSS Distributions }
1006*43a90889SApple OSS Distributions memcpy(ft_data, lp_data, lp->lp_pub_data_size);
1007*43a90889SApple OSS Distributions }
1008*43a90889SApple OSS Distributions
1009*43a90889SApple OSS Distributions static inline void
log_stats_update_saved(firehose_stream_t stream)1010*43a90889SApple OSS Distributions log_stats_update_saved(firehose_stream_t stream)
1011*43a90889SApple OSS Distributions {
1012*43a90889SApple OSS Distributions if (__improbable(!oslog_boot_done)) {
1013*43a90889SApple OSS Distributions stream = firehose_stream_persist;
1014*43a90889SApple OSS Distributions }
1015*43a90889SApple OSS Distributions
1016*43a90889SApple OSS Distributions switch (stream) {
1017*43a90889SApple OSS Distributions case firehose_stream_metadata:
1018*43a90889SApple OSS Distributions counter_inc(&oslog_p_metadata_saved_msgcount);
1019*43a90889SApple OSS Distributions break;
1020*43a90889SApple OSS Distributions case firehose_stream_persist:
1021*43a90889SApple OSS Distributions case firehose_stream_memory:
1022*43a90889SApple OSS Distributions case firehose_stream_special:
1023*43a90889SApple OSS Distributions counter_inc(&oslog_p_saved_msgcount);
1024*43a90889SApple OSS Distributions break;
1025*43a90889SApple OSS Distributions case firehose_stream_signpost:
1026*43a90889SApple OSS Distributions counter_inc(&oslog_p_signpost_saved_msgcount);
1027*43a90889SApple OSS Distributions break;
1028*43a90889SApple OSS Distributions default:
1029*43a90889SApple OSS Distributions panic("Unexpected firehose stream type %u", stream);
1030*43a90889SApple OSS Distributions }
1031*43a90889SApple OSS Distributions }
1032*43a90889SApple OSS Distributions
1033*43a90889SApple OSS Distributions static inline firehose_tracepoint_id_t
firehose_trace(const log_payload_s * lp,const uint8_t * lp_data)1034*43a90889SApple OSS Distributions firehose_trace(const log_payload_s *lp, const uint8_t *lp_data)
1035*43a90889SApple OSS Distributions {
1036*43a90889SApple OSS Distributions uint8_t *ft_priv_data = NULL;
1037*43a90889SApple OSS Distributions firehose_tracepoint_t ft = firehose_trace_start(lp, &ft_priv_data);
1038*43a90889SApple OSS Distributions
1039*43a90889SApple OSS Distributions if (fastpath(ft)) {
1040*43a90889SApple OSS Distributions firehose_trace_save_payload(lp, lp_data, ft, ft_priv_data);
1041*43a90889SApple OSS Distributions firehose_trace_finish(ft, lp->lp_ftid);
1042*43a90889SApple OSS Distributions log_stats_update_saved(lp->lp_stream);
1043*43a90889SApple OSS Distributions return lp->lp_ftid.ftid_value;
1044*43a90889SApple OSS Distributions }
1045*43a90889SApple OSS Distributions return 0;
1046*43a90889SApple OSS Distributions }
1047*43a90889SApple OSS Distributions
1048*43a90889SApple OSS Distributions static firehose_tracepoint_code_t
coproc_reg_type_to_firehost_code(os_log_coproc_reg_t reg_type)1049*43a90889SApple OSS Distributions coproc_reg_type_to_firehost_code(os_log_coproc_reg_t reg_type)
1050*43a90889SApple OSS Distributions {
1051*43a90889SApple OSS Distributions switch (reg_type) {
1052*43a90889SApple OSS Distributions case os_log_coproc_register_memory:
1053*43a90889SApple OSS Distributions return firehose_tracepoint_code_load_memory;
1054*43a90889SApple OSS Distributions case os_log_coproc_register_harvest_fs_ftab:
1055*43a90889SApple OSS Distributions return firehose_tracepoint_code_load_filesystem_ftab;
1056*43a90889SApple OSS Distributions default:
1057*43a90889SApple OSS Distributions return firehose_tracepoint_code_invalid;
1058*43a90889SApple OSS Distributions }
1059*43a90889SApple OSS Distributions }
1060*43a90889SApple OSS Distributions
1061*43a90889SApple OSS Distributions void
os_log_coprocessor_register_with_type(const char * uuid,const char * file_path,os_log_coproc_reg_t reg_type)1062*43a90889SApple OSS Distributions os_log_coprocessor_register_with_type(const char *uuid, const char *file_path, os_log_coproc_reg_t reg_type)
1063*43a90889SApple OSS Distributions {
1064*43a90889SApple OSS Distributions size_t path_size = strlen(file_path) + 1;
1065*43a90889SApple OSS Distributions size_t uuid_info_len = sizeof(struct firehose_trace_uuid_info_s) + path_size;
1066*43a90889SApple OSS Distributions
1067*43a90889SApple OSS Distributions if (os_log_disabled() || path_size > PATH_MAX) {
1068*43a90889SApple OSS Distributions return;
1069*43a90889SApple OSS Distributions }
1070*43a90889SApple OSS Distributions
1071*43a90889SApple OSS Distributions __attribute__((uninitialized))
1072*43a90889SApple OSS Distributions union {
1073*43a90889SApple OSS Distributions struct firehose_trace_uuid_info_s uuid_info;
1074*43a90889SApple OSS Distributions char path[PATH_MAX + sizeof(struct firehose_trace_uuid_info_s)];
1075*43a90889SApple OSS Distributions } buf;
1076*43a90889SApple OSS Distributions
1077*43a90889SApple OSS Distributions // write metadata to uuid_info
1078*43a90889SApple OSS Distributions memcpy(buf.uuid_info.ftui_uuid, uuid, sizeof(uuid_t));
1079*43a90889SApple OSS Distributions buf.uuid_info.ftui_size = 1;
1080*43a90889SApple OSS Distributions buf.uuid_info.ftui_address = 1;
1081*43a90889SApple OSS Distributions
1082*43a90889SApple OSS Distributions uint64_t stamp = firehose_tracepoint_time(firehose_activity_flags_default);
1083*43a90889SApple OSS Distributions
1084*43a90889SApple OSS Distributions // create tracepoint id
1085*43a90889SApple OSS Distributions firehose_tracepoint_id_u trace_id;
1086*43a90889SApple OSS Distributions trace_id.ftid_value = FIREHOSE_TRACE_ID_MAKE(firehose_tracepoint_namespace_metadata,
1087*43a90889SApple OSS Distributions _firehose_tracepoint_type_metadata_coprocessor, (firehose_tracepoint_flags_t)0,
1088*43a90889SApple OSS Distributions coproc_reg_type_to_firehost_code(reg_type));
1089*43a90889SApple OSS Distributions
1090*43a90889SApple OSS Distributions // write path to buffer
1091*43a90889SApple OSS Distributions memcpy(buf.uuid_info.ftui_path, file_path, path_size);
1092*43a90889SApple OSS Distributions
1093*43a90889SApple OSS Distributions // send metadata tracepoint to firehose for coprocessor registration in logd
1094*43a90889SApple OSS Distributions os_log_encoded_metadata(trace_id, stamp, (void *)&buf, uuid_info_len);
1095*43a90889SApple OSS Distributions }
1096*43a90889SApple OSS Distributions
1097*43a90889SApple OSS Distributions bool
log_payload_send(log_payload_t lp,const void * lp_data,bool use_stream)1098*43a90889SApple OSS Distributions log_payload_send(log_payload_t lp, const void *lp_data, bool use_stream)
1099*43a90889SApple OSS Distributions {
1100*43a90889SApple OSS Distributions if (use_stream) {
1101*43a90889SApple OSS Distributions bool is_metadata = (lp->lp_stream == firehose_stream_metadata);
1102*43a90889SApple OSS Distributions oslog_stream(is_metadata, lp->lp_ftid, lp->lp_timestamp, lp_data, lp->lp_data_size);
1103*43a90889SApple OSS Distributions }
1104*43a90889SApple OSS Distributions return firehose_trace(lp, lp_data) != 0;
1105*43a90889SApple OSS Distributions }
1106*43a90889SApple OSS Distributions
1107*43a90889SApple OSS Distributions void
__firehose_buffer_push_to_logd(firehose_buffer_t fb __unused,bool for_io __unused)1108*43a90889SApple OSS Distributions __firehose_buffer_push_to_logd(firehose_buffer_t fb __unused, bool for_io __unused)
1109*43a90889SApple OSS Distributions {
1110*43a90889SApple OSS Distributions oslogwakeup();
1111*43a90889SApple OSS Distributions return;
1112*43a90889SApple OSS Distributions }
1113*43a90889SApple OSS Distributions
1114*43a90889SApple OSS Distributions void
__firehose_allocate(vm_offset_t * addr,vm_size_t size __unused)1115*43a90889SApple OSS Distributions __firehose_allocate(vm_offset_t *addr, vm_size_t size __unused)
1116*43a90889SApple OSS Distributions {
1117*43a90889SApple OSS Distributions firehose_chunk_t kernel_buffer = (firehose_chunk_t)kernel_firehose_addr;
1118*43a90889SApple OSS Distributions
1119*43a90889SApple OSS Distributions if (kernel_firehose_addr) {
1120*43a90889SApple OSS Distributions *addr = kernel_firehose_addr;
1121*43a90889SApple OSS Distributions } else {
1122*43a90889SApple OSS Distributions *addr = 0;
1123*43a90889SApple OSS Distributions return;
1124*43a90889SApple OSS Distributions }
1125*43a90889SApple OSS Distributions // Now that we are done adding logs to this chunk, set the number of writers to 0
1126*43a90889SApple OSS Distributions // Without this, logd won't flush when the page is full
1127*43a90889SApple OSS Distributions firehose_boot_chunk.fc_pos.fcp_refcnt = 0;
1128*43a90889SApple OSS Distributions memcpy(&kernel_buffer[FIREHOSE_BUFFER_KERNEL_CHUNK_COUNT - 1], (const void *)&firehose_boot_chunk, FIREHOSE_CHUNK_SIZE);
1129*43a90889SApple OSS Distributions return;
1130*43a90889SApple OSS Distributions }
1131*43a90889SApple OSS Distributions // There isnt a lock held in this case.
1132*43a90889SApple OSS Distributions void
__firehose_critical_region_enter(void)1133*43a90889SApple OSS Distributions __firehose_critical_region_enter(void)
1134*43a90889SApple OSS Distributions {
1135*43a90889SApple OSS Distributions disable_preemption();
1136*43a90889SApple OSS Distributions return;
1137*43a90889SApple OSS Distributions }
1138*43a90889SApple OSS Distributions
1139*43a90889SApple OSS Distributions void
__firehose_critical_region_leave(void)1140*43a90889SApple OSS Distributions __firehose_critical_region_leave(void)
1141*43a90889SApple OSS Distributions {
1142*43a90889SApple OSS Distributions enable_preemption();
1143*43a90889SApple OSS Distributions return;
1144*43a90889SApple OSS Distributions }
1145*43a90889SApple OSS Distributions
1146*43a90889SApple OSS Distributions #ifdef CONFIG_XNUPOST
1147*43a90889SApple OSS Distributions
1148*43a90889SApple OSS Distributions static_assert(&_os_log_default == OS_LOG_DEFAULT,
1149*43a90889SApple OSS Distributions "OS_LOG_DEFAULT is an alias to _os_log_default");
1150*43a90889SApple OSS Distributions static_assert(OS_LOG_DISABLED == NULL,
1151*43a90889SApple OSS Distributions "OS_LOG_DISABLED handle is defined as NULL");
1152*43a90889SApple OSS Distributions
1153*43a90889SApple OSS Distributions #include <dev/random/randomdev.h>
1154*43a90889SApple OSS Distributions #include <tests/xnupost.h>
1155*43a90889SApple OSS Distributions
1156*43a90889SApple OSS Distributions typedef struct {
1157*43a90889SApple OSS Distributions size_t total;
1158*43a90889SApple OSS Distributions size_t saved;
1159*43a90889SApple OSS Distributions size_t dropped;
1160*43a90889SApple OSS Distributions size_t truncated;
1161*43a90889SApple OSS Distributions size_t errors;
1162*43a90889SApple OSS Distributions size_t errors_kc;
1163*43a90889SApple OSS Distributions size_t errors_fmt;
1164*43a90889SApple OSS Distributions size_t errors_max_args;
1165*43a90889SApple OSS Distributions } log_stats_t;
1166*43a90889SApple OSS Distributions
1167*43a90889SApple OSS Distributions #define TESTBUFLEN 256
1168*43a90889SApple OSS Distributions #define TESTOSLOGFMT(fn_name) "%u^%llu/%llu^kernel^0^test^" fn_name
1169*43a90889SApple OSS Distributions #define TESTOSLOGPFX "TESTLOG:%u#"
1170*43a90889SApple OSS Distributions #define TESTOSLOG(fn_name) TESTOSLOGPFX TESTOSLOGFMT(fn_name "#")
1171*43a90889SApple OSS Distributions
1172*43a90889SApple OSS Distributions #define LOG_STAT_CMP(cmp, b, a, e, stat, msg, test) \
1173*43a90889SApple OSS Distributions { \
1174*43a90889SApple OSS Distributions size_t n##stat = (a)->stat - (b)->stat; \
1175*43a90889SApple OSS Distributions size_t n##expected = (e)->stat; \
1176*43a90889SApple OSS Distributions cmp(n##stat, n##expected, (msg), (test), n##expected); \
1177*43a90889SApple OSS Distributions }
1178*43a90889SApple OSS Distributions #define LOG_STAT_EQ(b, a, e, stat, msg, test) \
1179*43a90889SApple OSS Distributions LOG_STAT_CMP(T_EXPECT_EQ_UINT, b, a, e, stat, msg, test)
1180*43a90889SApple OSS Distributions #define LOG_STAT_GE(b, a, e, stat, msg, test) \
1181*43a90889SApple OSS Distributions LOG_STAT_CMP(T_EXPECT_GE_UINT, b, a, e, stat, msg, test)
1182*43a90889SApple OSS Distributions
1183*43a90889SApple OSS Distributions #define GENOSLOGHELPER(fname, ident, callout_f) \
1184*43a90889SApple OSS Distributions static void \
1185*43a90889SApple OSS Distributions fname(uint32_t uniqid, uint64_t count, log_stats_t *before, log_stats_t *after) \
1186*43a90889SApple OSS Distributions { \
1187*43a90889SApple OSS Distributions uint32_t checksum = 0; \
1188*43a90889SApple OSS Distributions char pattern[TESTBUFLEN]; \
1189*43a90889SApple OSS Distributions T_LOG("Testing " ident "() with %d logs", count); \
1190*43a90889SApple OSS Distributions log_stats_get(before); \
1191*43a90889SApple OSS Distributions for (uint64_t i = 0; i < count; i++) { \
1192*43a90889SApple OSS Distributions (void) save_pattern(pattern, &checksum, TESTOSLOGFMT(ident), uniqid, i + 1, count); \
1193*43a90889SApple OSS Distributions callout_f(OS_LOG_DEFAULT, TESTOSLOG(ident), checksum, uniqid, i + 1, count); \
1194*43a90889SApple OSS Distributions } \
1195*43a90889SApple OSS Distributions log_stats_get(after); \
1196*43a90889SApple OSS Distributions }
1197*43a90889SApple OSS Distributions
1198*43a90889SApple OSS Distributions extern size_t find_pattern_in_buffer(const char *, size_t, size_t);
1199*43a90889SApple OSS Distributions
1200*43a90889SApple OSS Distributions void test_oslog_handleOSLogCtl(int32_t *, int32_t *, int32_t);
1201*43a90889SApple OSS Distributions kern_return_t test_printf(void);
1202*43a90889SApple OSS Distributions kern_return_t test_os_log(void);
1203*43a90889SApple OSS Distributions kern_return_t test_os_log_handles(void);
1204*43a90889SApple OSS Distributions kern_return_t test_os_log_parallel(void);
1205*43a90889SApple OSS Distributions
1206*43a90889SApple OSS Distributions SCALABLE_COUNTER_DECLARE(oslog_p_fmt_invalid_msgcount);
1207*43a90889SApple OSS Distributions SCALABLE_COUNTER_DECLARE(oslog_p_fmt_max_args_msgcount);
1208*43a90889SApple OSS Distributions SCALABLE_COUNTER_DECLARE(oslog_p_truncated_msgcount);
1209*43a90889SApple OSS Distributions SCALABLE_COUNTER_DECLARE(log_queue_cnt_received);
1210*43a90889SApple OSS Distributions
1211*43a90889SApple OSS Distributions static void
log_stats_get(log_stats_t * stats)1212*43a90889SApple OSS Distributions log_stats_get(log_stats_t *stats)
1213*43a90889SApple OSS Distributions {
1214*43a90889SApple OSS Distributions if (!stats) {
1215*43a90889SApple OSS Distributions return;
1216*43a90889SApple OSS Distributions }
1217*43a90889SApple OSS Distributions stats->total = counter_load(&oslog_p_total_msgcount);
1218*43a90889SApple OSS Distributions stats->saved = counter_load(&log_queue_cnt_received);
1219*43a90889SApple OSS Distributions stats->dropped = counter_load(&oslog_p_dropped_msgcount);
1220*43a90889SApple OSS Distributions stats->truncated = counter_load(&oslog_p_truncated_msgcount);
1221*43a90889SApple OSS Distributions stats->errors = counter_load(&oslog_p_error_count);
1222*43a90889SApple OSS Distributions stats->errors_kc = counter_load(&oslog_p_unresolved_kc_msgcount);
1223*43a90889SApple OSS Distributions stats->errors_fmt = counter_load(&oslog_p_fmt_invalid_msgcount);
1224*43a90889SApple OSS Distributions stats->errors_max_args = counter_load(&oslog_p_fmt_max_args_msgcount);
1225*43a90889SApple OSS Distributions }
1226*43a90889SApple OSS Distributions
1227*43a90889SApple OSS Distributions static void
log_stats_diff(const log_stats_t * before,const log_stats_t * after,log_stats_t * diff)1228*43a90889SApple OSS Distributions log_stats_diff(const log_stats_t *before, const log_stats_t *after, log_stats_t *diff)
1229*43a90889SApple OSS Distributions {
1230*43a90889SApple OSS Distributions log_stats_t d = {};
1231*43a90889SApple OSS Distributions
1232*43a90889SApple OSS Distributions if (before) {
1233*43a90889SApple OSS Distributions d = *before;
1234*43a90889SApple OSS Distributions }
1235*43a90889SApple OSS Distributions if (after) {
1236*43a90889SApple OSS Distributions d.total = after->total - d.total;
1237*43a90889SApple OSS Distributions d.saved = after->saved - d.saved;
1238*43a90889SApple OSS Distributions d.dropped = after->dropped - d.dropped;
1239*43a90889SApple OSS Distributions d.truncated = after->truncated - d.truncated;
1240*43a90889SApple OSS Distributions d.errors = after->errors - d.errors;
1241*43a90889SApple OSS Distributions d.errors_kc = after->errors_kc - d.errors_kc;
1242*43a90889SApple OSS Distributions d.errors_fmt = after->errors_fmt - d.errors_fmt;
1243*43a90889SApple OSS Distributions d.errors_max_args = after->errors_max_args - d.errors_max_args;
1244*43a90889SApple OSS Distributions }
1245*43a90889SApple OSS Distributions *diff = d;
1246*43a90889SApple OSS Distributions }
1247*43a90889SApple OSS Distributions
1248*43a90889SApple OSS Distributions static void
log_stats_check_errors(const log_stats_t * before,const log_stats_t * after,const log_stats_t * expected,const char * test)1249*43a90889SApple OSS Distributions log_stats_check_errors(const log_stats_t *before, const log_stats_t *after, const log_stats_t *expected,
1250*43a90889SApple OSS Distributions const char *test)
1251*43a90889SApple OSS Distributions {
1252*43a90889SApple OSS Distributions LOG_STAT_EQ(before, after, expected, errors, "%s: Expected %lu encoding errors", test);
1253*43a90889SApple OSS Distributions LOG_STAT_EQ(before, after, expected, errors_kc, "%s: Expected %lu DSO errors", test);
1254*43a90889SApple OSS Distributions LOG_STAT_EQ(before, after, expected, errors_fmt, "%s: Expected %lu bad format errors", test);
1255*43a90889SApple OSS Distributions LOG_STAT_EQ(before, after, expected, errors_max_args, "%s: Expected %lu max arguments errors", test);
1256*43a90889SApple OSS Distributions }
1257*43a90889SApple OSS Distributions
1258*43a90889SApple OSS Distributions static void
log_stats_check(const log_stats_t * before,const log_stats_t * after,const log_stats_t * expected,const char * test)1259*43a90889SApple OSS Distributions log_stats_check(const log_stats_t *before, const log_stats_t *after, const log_stats_t *expected,
1260*43a90889SApple OSS Distributions const char *test)
1261*43a90889SApple OSS Distributions {
1262*43a90889SApple OSS Distributions /*
1263*43a90889SApple OSS Distributions * The comparison is >= (_GE) for total and saved counters because tests
1264*43a90889SApple OSS Distributions * are running while the system is up and potentially logging. Test and
1265*43a90889SApple OSS Distributions * regular logs interfere rather rarely but can make the test flaky
1266*43a90889SApple OSS Distributions * which is not desired.
1267*43a90889SApple OSS Distributions */
1268*43a90889SApple OSS Distributions LOG_STAT_GE(before, after, expected, total, "%s: Expected %lu logs total", test);
1269*43a90889SApple OSS Distributions LOG_STAT_GE(before, after, expected, saved, "%s: Expected %lu saved logs", test);
1270*43a90889SApple OSS Distributions LOG_STAT_EQ(before, after, expected, dropped, "%s: Expected %lu logs dropped", test);
1271*43a90889SApple OSS Distributions log_stats_check_errors(before, after, expected, test);
1272*43a90889SApple OSS Distributions }
1273*43a90889SApple OSS Distributions
1274*43a90889SApple OSS Distributions static void
log_stats_report(const log_stats_t * before,const log_stats_t * after,const char * test)1275*43a90889SApple OSS Distributions log_stats_report(const log_stats_t *before, const log_stats_t *after, const char *test)
1276*43a90889SApple OSS Distributions {
1277*43a90889SApple OSS Distributions log_stats_t diff = {};
1278*43a90889SApple OSS Distributions log_stats_diff(before, after, &diff);
1279*43a90889SApple OSS Distributions
1280*43a90889SApple OSS Distributions T_LOG("\n%s: Logging stats:\n\ttotal: %u\n\tsaved: %u\n\tdropped: %u\n"
1281*43a90889SApple OSS Distributions "\terrors: %u\n\terrors_kc: %u\n\terrors_fmt: %u\n\terrors_max_args: %u",
1282*43a90889SApple OSS Distributions test, diff.total, diff.saved, diff.dropped,
1283*43a90889SApple OSS Distributions diff.errors, diff.errors_kc, diff.errors_fmt, diff.errors_max_args);
1284*43a90889SApple OSS Distributions }
1285*43a90889SApple OSS Distributions
1286*43a90889SApple OSS Distributions static int
save_pattern(char buf[static TESTBUFLEN],uint32_t * crc,const char * fmt,...)1287*43a90889SApple OSS Distributions save_pattern(char buf[static TESTBUFLEN], uint32_t *crc, const char *fmt, ...)
1288*43a90889SApple OSS Distributions {
1289*43a90889SApple OSS Distributions va_list va;
1290*43a90889SApple OSS Distributions
1291*43a90889SApple OSS Distributions va_start(va, fmt);
1292*43a90889SApple OSS Distributions #pragma clang diagnostic push
1293*43a90889SApple OSS Distributions #pragma clang diagnostic ignored "-Wformat-nonliteral"
1294*43a90889SApple OSS Distributions int n = vscnprintf(buf, TESTBUFLEN, fmt, va);
1295*43a90889SApple OSS Distributions #pragma clang diagnostic pop
1296*43a90889SApple OSS Distributions va_end(va);
1297*43a90889SApple OSS Distributions if (crc) {
1298*43a90889SApple OSS Distributions *crc = crc32(0, buf, n);
1299*43a90889SApple OSS Distributions }
1300*43a90889SApple OSS Distributions return n;
1301*43a90889SApple OSS Distributions }
1302*43a90889SApple OSS Distributions
1303*43a90889SApple OSS Distributions /*
1304*43a90889SApple OSS Distributions * Actual GENOSLOGHELPER() 2nd argument values below are expected by libtrace
1305*43a90889SApple OSS Distributions * test_kern_oslog test suite and shall not be changed without updating given
1306*43a90889SApple OSS Distributions * test suite.
1307*43a90889SApple OSS Distributions */
1308*43a90889SApple OSS Distributions GENOSLOGHELPER(test_oslog_info, "oslog_info_helper", os_log_info);
1309*43a90889SApple OSS Distributions GENOSLOGHELPER(test_oslog_fault, "oslog_fault_helper", os_log_fault);
1310*43a90889SApple OSS Distributions GENOSLOGHELPER(test_oslog_debug, "oslog_debug_helper", os_log_debug);
1311*43a90889SApple OSS Distributions GENOSLOGHELPER(test_oslog_error, "oslog_error_helper", os_log_error);
1312*43a90889SApple OSS Distributions GENOSLOGHELPER(test_oslog_default, "oslog_default_helper", os_log);
1313*43a90889SApple OSS Distributions
1314*43a90889SApple OSS Distributions kern_return_t
test_printf(void)1315*43a90889SApple OSS Distributions test_printf(void)
1316*43a90889SApple OSS Distributions {
1317*43a90889SApple OSS Distributions const uint32_t uniqid = RandomULong();
1318*43a90889SApple OSS Distributions T_ASSERT_NE_UINT(0, uniqid, "Random number should not be zero");
1319*43a90889SApple OSS Distributions
1320*43a90889SApple OSS Distributions uint64_t stamp = mach_absolute_time();
1321*43a90889SApple OSS Distributions T_ASSERT_NE_ULLONG(0, stamp, "Absolute time should not be zero");
1322*43a90889SApple OSS Distributions
1323*43a90889SApple OSS Distributions T_LOG("Validating with atm_diagnostic_config=%#x uniqid=%u stamp=%llu",
1324*43a90889SApple OSS Distributions atm_get_diagnostic_config(), uniqid, stamp);
1325*43a90889SApple OSS Distributions
1326*43a90889SApple OSS Distributions __attribute__((uninitialized))
1327*43a90889SApple OSS Distributions char pattern[TESTBUFLEN];
1328*43a90889SApple OSS Distributions log_stats_t before = {}, after = {};
1329*43a90889SApple OSS Distributions uint32_t checksum = 0;
1330*43a90889SApple OSS Distributions
1331*43a90889SApple OSS Distributions log_stats_get(&before);
1332*43a90889SApple OSS Distributions
1333*43a90889SApple OSS Distributions (void) save_pattern(pattern, &checksum, TESTOSLOGFMT("printf_only"), uniqid, 1LL, 2LL);
1334*43a90889SApple OSS Distributions printf(TESTOSLOG("printf_only") "mat%llu\n", checksum, uniqid, 1LL, 2LL, stamp);
1335*43a90889SApple OSS Distributions
1336*43a90889SApple OSS Distributions (void) save_pattern(pattern, &checksum, TESTOSLOGFMT("printf_only"), uniqid, 2LL, 2LL);
1337*43a90889SApple OSS Distributions printf(TESTOSLOG("printf_only") "mat%llu\n", checksum, uniqid, 2LL, 2LL, stamp);
1338*43a90889SApple OSS Distributions
1339*43a90889SApple OSS Distributions size_t saved = save_pattern(pattern, NULL, "kernel^0^test^printf_only#mat%llu", stamp);
1340*43a90889SApple OSS Distributions size_t match_count = find_pattern_in_buffer(pattern, saved, 2LL);
1341*43a90889SApple OSS Distributions T_EXPECT_EQ_ULONG(match_count, 2LL, "printf() logs to msgbuf");
1342*43a90889SApple OSS Distributions
1343*43a90889SApple OSS Distributions log_stats_get(&after);
1344*43a90889SApple OSS Distributions
1345*43a90889SApple OSS Distributions if (!os_log_turned_off()) {
1346*43a90889SApple OSS Distributions // printf() should log to OSLog with OSLog enabled.
1347*43a90889SApple OSS Distributions log_stats_t expected = { .total = 2, .saved = 2 };
1348*43a90889SApple OSS Distributions log_stats_check(&before, &after, &expected, "printf() logs to oslog");
1349*43a90889SApple OSS Distributions }
1350*43a90889SApple OSS Distributions
1351*43a90889SApple OSS Distributions log_stats_report(&before, &after, __FUNCTION__);
1352*43a90889SApple OSS Distributions
1353*43a90889SApple OSS Distributions return KERN_SUCCESS;
1354*43a90889SApple OSS Distributions }
1355*43a90889SApple OSS Distributions
1356*43a90889SApple OSS Distributions static void
verify_os_log(struct os_log_s * h,char * sub,char * cat)1357*43a90889SApple OSS Distributions verify_os_log(struct os_log_s *h, char *sub, char *cat)
1358*43a90889SApple OSS Distributions {
1359*43a90889SApple OSS Distributions const size_t sub_len = os_log_subsystem_name_size(sub);
1360*43a90889SApple OSS Distributions const size_t cat_len = os_log_subsystem_name_size(cat);
1361*43a90889SApple OSS Distributions
1362*43a90889SApple OSS Distributions struct os_log_subsystem_s *s = &h->ol_subsystem;
1363*43a90889SApple OSS Distributions
1364*43a90889SApple OSS Distributions T_ASSERT_EQ_STR(s->ols_name, sub, "Log subsystem name is %s", sub);
1365*43a90889SApple OSS Distributions T_ASSERT_EQ_ULONG(s->ols_sub_size, sub_len, "Log subsystem size is %lu", sub_len);
1366*43a90889SApple OSS Distributions T_ASSERT_EQ_ULONG(strlen(s->ols_name), sub_len - 1, "Log subsystem length is %lu", sub_len - 1);
1367*43a90889SApple OSS Distributions
1368*43a90889SApple OSS Distributions T_ASSERT_EQ_STR(&s->ols_name[sub_len], cat, "Log category name is %s", cat);
1369*43a90889SApple OSS Distributions T_ASSERT_EQ_ULONG(s->ols_cat_size, cat_len, "Log category length is %lu", cat_len);
1370*43a90889SApple OSS Distributions T_ASSERT_EQ_ULONG(strlen(&s->ols_name[sub_len]), cat_len - 1, "Log category size is %lu", cat_len - 1);
1371*43a90889SApple OSS Distributions }
1372*43a90889SApple OSS Distributions
1373*43a90889SApple OSS Distributions static os_log_t
create_verified_os_log(char * sub,char * cat)1374*43a90889SApple OSS Distributions create_verified_os_log(char *sub, char *cat)
1375*43a90889SApple OSS Distributions {
1376*43a90889SApple OSS Distributions os_log_t h = os_log_create(sub, cat);
1377*43a90889SApple OSS Distributions verify_os_log(h, sub, cat);
1378*43a90889SApple OSS Distributions return h;
1379*43a90889SApple OSS Distributions }
1380*43a90889SApple OSS Distributions
1381*43a90889SApple OSS Distributions kern_return_t
test_os_log_handles(void)1382*43a90889SApple OSS Distributions test_os_log_handles(void)
1383*43a90889SApple OSS Distributions {
1384*43a90889SApple OSS Distributions os_log_t h1 = create_verified_os_log("xnu_post_subsystem1", "xnu_post_category1");
1385*43a90889SApple OSS Distributions if (os_log_disabled()) {
1386*43a90889SApple OSS Distributions T_ASSERT_EQ_PTR(h1, OS_LOG_DISABLED, "Disabled logging uses OS_LOG_DISABLED");
1387*43a90889SApple OSS Distributions return KERN_SUCCESS;
1388*43a90889SApple OSS Distributions }
1389*43a90889SApple OSS Distributions T_ASSERT_NE_PTR(h1, OS_LOG_DEFAULT, "Custom log handle is not OS_LOG_DEFAULT");
1390*43a90889SApple OSS Distributions
1391*43a90889SApple OSS Distributions os_log_t h2 = create_verified_os_log("xnu_post_subsystem1", "xnu_post_category1");
1392*43a90889SApple OSS Distributions T_ASSERT_EQ_PTR(h1, h2, "os_log_create() finds an existing log handle in the cache");
1393*43a90889SApple OSS Distributions
1394*43a90889SApple OSS Distributions h2 = create_verified_os_log("xnu_post_subsystem1", "xnu_post_category2");
1395*43a90889SApple OSS Distributions T_ASSERT_NE_PTR(h1, h2, "Subsystem is not enough to identify a log handle");
1396*43a90889SApple OSS Distributions
1397*43a90889SApple OSS Distributions h2 = create_verified_os_log("xnu_post_subsystem2", "xnu_post_category1");
1398*43a90889SApple OSS Distributions T_ASSERT_NE_PTR(h1, h2, "Category is not enough to identify a log handle");
1399*43a90889SApple OSS Distributions
1400*43a90889SApple OSS Distributions h2 = create_verified_os_log("xnu_post_subsystem3", "xnu_post_category3");
1401*43a90889SApple OSS Distributions T_ASSERT_NE_PTR(h1, h2, "Different subsystem and category yield a different handle");
1402*43a90889SApple OSS Distributions
1403*43a90889SApple OSS Distributions h1 = h2;
1404*43a90889SApple OSS Distributions h2 = create_verified_os_log("xnu_post", "_subsystem3xnu_post_category3");
1405*43a90889SApple OSS Distributions T_ASSERT_NE_PTR(h1, h2, "Subsystem and category cannot be mixed");
1406*43a90889SApple OSS Distributions
1407*43a90889SApple OSS Distributions const size_t name_size = sizeof(h1->ol_subsystem.ols_name) / 2;
1408*43a90889SApple OSS Distributions
1409*43a90889SApple OSS Distributions char super_long_sub[name_size] = {
1410*43a90889SApple OSS Distributions [0 ... sizeof(super_long_sub) - 1] = 'X'
1411*43a90889SApple OSS Distributions };
1412*43a90889SApple OSS Distributions
1413*43a90889SApple OSS Distributions char super_long_cat[name_size] = {
1414*43a90889SApple OSS Distributions [0 ... sizeof(super_long_sub) - 1] = 'Y'
1415*43a90889SApple OSS Distributions };
1416*43a90889SApple OSS Distributions
1417*43a90889SApple OSS Distributions h1 = os_log_create(super_long_sub, super_long_cat);
1418*43a90889SApple OSS Distributions T_ASSERT_NE_PTR(h1, OS_LOG_DEFAULT, "Custom log handle is not OS_LOG_DEFAULT");
1419*43a90889SApple OSS Distributions
1420*43a90889SApple OSS Distributions super_long_sub[name_size - 1] = '\0';
1421*43a90889SApple OSS Distributions super_long_cat[name_size - 1] = '\0';
1422*43a90889SApple OSS Distributions
1423*43a90889SApple OSS Distributions verify_os_log(h1, super_long_sub, super_long_cat);
1424*43a90889SApple OSS Distributions
1425*43a90889SApple OSS Distributions return KERN_SUCCESS;
1426*43a90889SApple OSS Distributions }
1427*43a90889SApple OSS Distributions
1428*43a90889SApple OSS Distributions kern_return_t
test_os_log(void)1429*43a90889SApple OSS Distributions test_os_log(void)
1430*43a90889SApple OSS Distributions {
1431*43a90889SApple OSS Distributions const uint32_t uniqid = RandomULong();
1432*43a90889SApple OSS Distributions T_ASSERT_NE_UINT(0, uniqid, "Random number should not be zero");
1433*43a90889SApple OSS Distributions
1434*43a90889SApple OSS Distributions uint64_t stamp = mach_absolute_time();
1435*43a90889SApple OSS Distributions T_ASSERT_NE_ULLONG(0, stamp, "Absolute time should not be zero");
1436*43a90889SApple OSS Distributions
1437*43a90889SApple OSS Distributions T_LOG("Validating with atm_diagnostic_config=%#x uniqid=%u stamp=%llu",
1438*43a90889SApple OSS Distributions atm_get_diagnostic_config(), uniqid, stamp);
1439*43a90889SApple OSS Distributions
1440*43a90889SApple OSS Distributions os_log_t log_handle = os_log_create("com.apple.xnu.test.t1", "kpost");
1441*43a90889SApple OSS Distributions T_ASSERT_NE_PTR(OS_LOG_DEFAULT, log_handle, "Log handle is not OS_LOG_DEFAULT");
1442*43a90889SApple OSS Distributions
1443*43a90889SApple OSS Distributions const bool enabled = !os_log_turned_off();
1444*43a90889SApple OSS Distributions T_ASSERT_EQ_INT(enabled, os_log_info_enabled(log_handle), "Info log level is enabled");
1445*43a90889SApple OSS Distributions T_ASSERT_EQ_INT(enabled, os_log_debug_enabled(log_handle), "Debug log level is enabled");
1446*43a90889SApple OSS Distributions
1447*43a90889SApple OSS Distributions __attribute__((uninitialized))
1448*43a90889SApple OSS Distributions char pattern[TESTBUFLEN];
1449*43a90889SApple OSS Distributions uint32_t checksum = 0;
1450*43a90889SApple OSS Distributions
1451*43a90889SApple OSS Distributions (void) save_pattern(pattern, &checksum, TESTOSLOGFMT("oslog_info"), uniqid, 1LL, 1LL);
1452*43a90889SApple OSS Distributions os_log_info(log_handle, TESTOSLOG("oslog_info") "mat%llu", checksum, uniqid, 1LL, 1LL, stamp);
1453*43a90889SApple OSS Distributions size_t saved = save_pattern(pattern, NULL, "kernel^0^test^oslog_info#mat%llu", stamp);
1454*43a90889SApple OSS Distributions size_t match_count = find_pattern_in_buffer(pattern, saved, 1LL);
1455*43a90889SApple OSS Distributions T_EXPECT_EQ_ULONG(match_count, 1LL, "oslog_info() logs to system message buffer");
1456*43a90889SApple OSS Distributions
1457*43a90889SApple OSS Distributions const size_t n = 10;
1458*43a90889SApple OSS Distributions
1459*43a90889SApple OSS Distributions log_stats_t expected = {
1460*43a90889SApple OSS Distributions .total = enabled ? n : 0,
1461*43a90889SApple OSS Distributions .saved = enabled ? n : 0
1462*43a90889SApple OSS Distributions };
1463*43a90889SApple OSS Distributions
1464*43a90889SApple OSS Distributions log_stats_t before = {}, after = {};
1465*43a90889SApple OSS Distributions
1466*43a90889SApple OSS Distributions test_oslog_info(uniqid, n, &before, &after);
1467*43a90889SApple OSS Distributions log_stats_check(&before, &after, &expected, "test_oslog_info");
1468*43a90889SApple OSS Distributions
1469*43a90889SApple OSS Distributions test_oslog_debug(uniqid, n, &before, &after);
1470*43a90889SApple OSS Distributions log_stats_check(&before, &after, &expected, "test_oslog_debug");
1471*43a90889SApple OSS Distributions
1472*43a90889SApple OSS Distributions test_oslog_error(uniqid, n, &before, &after);
1473*43a90889SApple OSS Distributions log_stats_check(&before, &after, &expected, "test_oslog_error");
1474*43a90889SApple OSS Distributions
1475*43a90889SApple OSS Distributions test_oslog_default(uniqid, n, &before, &after);
1476*43a90889SApple OSS Distributions log_stats_check(&before, &after, &expected, "test_oslog_default");
1477*43a90889SApple OSS Distributions
1478*43a90889SApple OSS Distributions test_oslog_fault(uniqid, n, &before, &after);
1479*43a90889SApple OSS Distributions log_stats_check(&before, &after, &expected, "test_oslog_fault");
1480*43a90889SApple OSS Distributions
1481*43a90889SApple OSS Distributions log_stats_report(&before, &after, __FUNCTION__);
1482*43a90889SApple OSS Distributions
1483*43a90889SApple OSS Distributions return KERN_SUCCESS;
1484*43a90889SApple OSS Distributions }
1485*43a90889SApple OSS Distributions
1486*43a90889SApple OSS Distributions static size_t _test_log_loop_count = 0;
1487*43a90889SApple OSS Distributions
1488*43a90889SApple OSS Distributions static void
_test_log_loop(void * arg __unused,wait_result_t wres __unused)1489*43a90889SApple OSS Distributions _test_log_loop(void *arg __unused, wait_result_t wres __unused)
1490*43a90889SApple OSS Distributions {
1491*43a90889SApple OSS Distributions test_oslog_debug(RandomULong(), 100, NULL, NULL);
1492*43a90889SApple OSS Distributions os_atomic_add(&_test_log_loop_count, 100, relaxed);
1493*43a90889SApple OSS Distributions }
1494*43a90889SApple OSS Distributions
1495*43a90889SApple OSS Distributions kern_return_t
test_os_log_parallel(void)1496*43a90889SApple OSS Distributions test_os_log_parallel(void)
1497*43a90889SApple OSS Distributions {
1498*43a90889SApple OSS Distributions if (os_log_turned_off()) {
1499*43a90889SApple OSS Distributions T_LOG("Logging disabled, skipping tests.");
1500*43a90889SApple OSS Distributions return KERN_SUCCESS;
1501*43a90889SApple OSS Distributions }
1502*43a90889SApple OSS Distributions
1503*43a90889SApple OSS Distributions thread_t thread[2];
1504*43a90889SApple OSS Distributions kern_return_t kr;
1505*43a90889SApple OSS Distributions log_stats_t after, before, expected = {};
1506*43a90889SApple OSS Distributions
1507*43a90889SApple OSS Distributions log_stats_get(&before);
1508*43a90889SApple OSS Distributions
1509*43a90889SApple OSS Distributions kr = kernel_thread_start(_test_log_loop, NULL, &thread[0]);
1510*43a90889SApple OSS Distributions T_ASSERT_EQ_INT(kr, KERN_SUCCESS, "kernel_thread_start returned successfully");
1511*43a90889SApple OSS Distributions
1512*43a90889SApple OSS Distributions kr = kernel_thread_start(_test_log_loop, NULL, &thread[1]);
1513*43a90889SApple OSS Distributions T_ASSERT_EQ_INT(kr, KERN_SUCCESS, "kernel_thread_start returned successfully");
1514*43a90889SApple OSS Distributions
1515*43a90889SApple OSS Distributions test_oslog_info(RandomULong(), 100, NULL, NULL);
1516*43a90889SApple OSS Distributions
1517*43a90889SApple OSS Distributions /* wait until other thread has also finished */
1518*43a90889SApple OSS Distributions while (_test_log_loop_count < 200) {
1519*43a90889SApple OSS Distributions delay(1000);
1520*43a90889SApple OSS Distributions }
1521*43a90889SApple OSS Distributions
1522*43a90889SApple OSS Distributions thread_deallocate(thread[0]);
1523*43a90889SApple OSS Distributions thread_deallocate(thread[1]);
1524*43a90889SApple OSS Distributions
1525*43a90889SApple OSS Distributions log_stats_get(&after);
1526*43a90889SApple OSS Distributions log_stats_check_errors(&before, &after, &expected, __FUNCTION__);
1527*43a90889SApple OSS Distributions log_stats_report(&before, &after, __FUNCTION__);
1528*43a90889SApple OSS Distributions
1529*43a90889SApple OSS Distributions return KERN_SUCCESS;
1530*43a90889SApple OSS Distributions }
1531*43a90889SApple OSS Distributions
1532*43a90889SApple OSS Distributions static kern_return_t
test_stresslog_dropmsg(const uint32_t uniqid)1533*43a90889SApple OSS Distributions test_stresslog_dropmsg(const uint32_t uniqid)
1534*43a90889SApple OSS Distributions {
1535*43a90889SApple OSS Distributions if (os_log_turned_off()) {
1536*43a90889SApple OSS Distributions T_LOG("Logging disabled, skipping tests.");
1537*43a90889SApple OSS Distributions return KERN_SUCCESS;
1538*43a90889SApple OSS Distributions }
1539*43a90889SApple OSS Distributions
1540*43a90889SApple OSS Distributions log_stats_t after, before, expected = {};
1541*43a90889SApple OSS Distributions
1542*43a90889SApple OSS Distributions test_oslog_debug(uniqid, 100, &before, &after);
1543*43a90889SApple OSS Distributions while ((after.dropped - before.dropped) == 0) {
1544*43a90889SApple OSS Distributions test_oslog_debug(uniqid, 100, NULL, &after);
1545*43a90889SApple OSS Distributions }
1546*43a90889SApple OSS Distributions
1547*43a90889SApple OSS Distributions log_stats_check_errors(&before, &after, &expected, __FUNCTION__);
1548*43a90889SApple OSS Distributions log_stats_report(&before, &after, __FUNCTION__);
1549*43a90889SApple OSS Distributions
1550*43a90889SApple OSS Distributions return KERN_SUCCESS;
1551*43a90889SApple OSS Distributions }
1552*43a90889SApple OSS Distributions
1553*43a90889SApple OSS Distributions void
test_oslog_handleOSLogCtl(int32_t * in,int32_t * out,int32_t len)1554*43a90889SApple OSS Distributions test_oslog_handleOSLogCtl(int32_t *in, int32_t *out, int32_t len)
1555*43a90889SApple OSS Distributions {
1556*43a90889SApple OSS Distributions if (!in || !out || len != 4) {
1557*43a90889SApple OSS Distributions return;
1558*43a90889SApple OSS Distributions }
1559*43a90889SApple OSS Distributions switch (in[0]) {
1560*43a90889SApple OSS Distributions case 1:
1561*43a90889SApple OSS Distributions {
1562*43a90889SApple OSS Distributions /* send out counters */
1563*43a90889SApple OSS Distributions out[1] = counter_load(&oslog_p_total_msgcount);
1564*43a90889SApple OSS Distributions out[2] = counter_load(&oslog_p_saved_msgcount);
1565*43a90889SApple OSS Distributions out[3] = counter_load(&oslog_p_dropped_msgcount);
1566*43a90889SApple OSS Distributions out[0] = KERN_SUCCESS;
1567*43a90889SApple OSS Distributions break;
1568*43a90889SApple OSS Distributions }
1569*43a90889SApple OSS Distributions case 2:
1570*43a90889SApple OSS Distributions {
1571*43a90889SApple OSS Distributions /* mini stress run */
1572*43a90889SApple OSS Distributions out[0] = test_os_log_parallel();
1573*43a90889SApple OSS Distributions break;
1574*43a90889SApple OSS Distributions }
1575*43a90889SApple OSS Distributions case 3:
1576*43a90889SApple OSS Distributions {
1577*43a90889SApple OSS Distributions /* drop msg tests */
1578*43a90889SApple OSS Distributions out[1] = RandomULong();
1579*43a90889SApple OSS Distributions out[0] = test_stresslog_dropmsg(out[1]);
1580*43a90889SApple OSS Distributions break;
1581*43a90889SApple OSS Distributions }
1582*43a90889SApple OSS Distributions case 4:
1583*43a90889SApple OSS Distributions {
1584*43a90889SApple OSS Distributions /* invoke log helpers */
1585*43a90889SApple OSS Distributions uint32_t uniqid = in[3];
1586*43a90889SApple OSS Distributions int32_t msgcount = in[2];
1587*43a90889SApple OSS Distributions if (uniqid == 0 || msgcount == 0) {
1588*43a90889SApple OSS Distributions out[0] = KERN_INVALID_VALUE;
1589*43a90889SApple OSS Distributions return;
1590*43a90889SApple OSS Distributions }
1591*43a90889SApple OSS Distributions
1592*43a90889SApple OSS Distributions switch (in[1]) {
1593*43a90889SApple OSS Distributions case OS_LOG_TYPE_INFO:
1594*43a90889SApple OSS Distributions test_oslog_info(uniqid, msgcount, NULL, NULL);
1595*43a90889SApple OSS Distributions break;
1596*43a90889SApple OSS Distributions case OS_LOG_TYPE_DEBUG:
1597*43a90889SApple OSS Distributions test_oslog_debug(uniqid, msgcount, NULL, NULL);
1598*43a90889SApple OSS Distributions break;
1599*43a90889SApple OSS Distributions case OS_LOG_TYPE_ERROR:
1600*43a90889SApple OSS Distributions test_oslog_error(uniqid, msgcount, NULL, NULL);
1601*43a90889SApple OSS Distributions break;
1602*43a90889SApple OSS Distributions case OS_LOG_TYPE_FAULT:
1603*43a90889SApple OSS Distributions test_oslog_fault(uniqid, msgcount, NULL, NULL);
1604*43a90889SApple OSS Distributions break;
1605*43a90889SApple OSS Distributions case OS_LOG_TYPE_DEFAULT:
1606*43a90889SApple OSS Distributions default:
1607*43a90889SApple OSS Distributions test_oslog_default(uniqid, msgcount, NULL, NULL);
1608*43a90889SApple OSS Distributions break;
1609*43a90889SApple OSS Distributions }
1610*43a90889SApple OSS Distributions out[0] = KERN_SUCCESS;
1611*43a90889SApple OSS Distributions break;
1612*43a90889SApple OSS Distributions /* end of case 4 */
1613*43a90889SApple OSS Distributions }
1614*43a90889SApple OSS Distributions default:
1615*43a90889SApple OSS Distributions {
1616*43a90889SApple OSS Distributions out[0] = KERN_INVALID_VALUE;
1617*43a90889SApple OSS Distributions break;
1618*43a90889SApple OSS Distributions }
1619*43a90889SApple OSS Distributions }
1620*43a90889SApple OSS Distributions return;
1621*43a90889SApple OSS Distributions }
1622*43a90889SApple OSS Distributions
1623*43a90889SApple OSS Distributions #endif /* CONFIG_XNUPOST */
1624