xref: /xnu-11215.41.3/osfmk/kern/ext_paniclog.c (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 /*
2  * Copyright (c) 2022 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #include <kern/locks.h>
30 #include <kern/kalloc.h>
31 #include <kern/zalloc.h>
32 #include <libkern/OSAtomic.h>
33 #include <os/log.h>
34 #include <sys/errno.h>
35 
36 #include <kern/ext_paniclog.h>
37 #include <kern/debug.h>
38 
39 #if defined(__arm64__)
40 #include <pexpert/pexpert.h> /* For gPanicBase */
41 #endif
42 
43 #if CONFIG_EXT_PANICLOG
44 
45 static LCK_GRP_DECLARE(ext_paniclog_lck_grp, "Extensible panic log locks");
46 static LCK_MTX_DECLARE(ext_paniclog_list_lock, &ext_paniclog_lck_grp);
47 
48 // Global slot for panic_with_data
49 ext_paniclog_handle_t *panic_with_data_handle;
50 
51 // Global to keep track of number of handles
52 uint32_t ext_paniclog_handle_count = 0;
53 
54 uint8_t ext_paniclog_panic_in_progress = 0;
55 
56 uint8_t ext_paniclog_panic_write_done = 0;
57 
58 uuid_string_t panic_with_data_uuid = PANIC_WITH_DATA_UUID;
59 
60 LIST_HEAD(_ext_paniclog_handle_list, ext_paniclog_handle) ext_paniclog_handle_list;
61 
62 void
ext_paniclog_init(void)63 ext_paniclog_init(void)
64 {
65 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG: Initializing list\n");
66 	LIST_INIT(&ext_paniclog_handle_list);
67 
68 	uuid_t uuid;
69 	panic_with_data_handle = ext_paniclog_handle_alloc_with_uuid(uuid,
70 	    PANIC_WITH_DATA_DATA_ID,
71 	    PANIC_WITH_DATA_MAX_LEN, EXT_PANICLOG_OPTIONS_NONE);
72 }
73 
74 ext_paniclog_handle_t *
ext_paniclog_handle_alloc_with_uuid(uuid_t uuid,const char * data_id,uint32_t max_len,ext_paniclog_create_options_t options)75 ext_paniclog_handle_alloc_with_uuid(uuid_t uuid, const char *data_id,
76     uint32_t max_len, ext_paniclog_create_options_t options)
77 {
78 	size_t data_id_size = strnlen(data_id, MAX_DATA_ID_SIZE - 1);
79 
80 	if (max_len > (MAX_EXT_PANICLOG_SIZE - data_id_size - sizeof(ext_paniclog_header_t))) {
81 		os_log_error(OS_LOG_DEFAULT, "EXT_PANICLOG_: Input len %d greater than max allowed %d\n",
82 		    max_len, MAX_EXT_PANICLOG_SIZE);
83 		return NULL;
84 	}
85 
86 	ext_paniclog_handle_t *handle = kalloc_type(ext_paniclog_handle_t, Z_WAITOK | Z_ZERO);
87 	if (!handle) {
88 		return NULL;
89 	}
90 
91 	/* We don't alloc a buffer if the create call is from a dext.
92 	 * In the Create call for dext, we use a IOBMD to backup this handle
93 	 */
94 
95 	if (!(options & EXT_PANICLOG_OPTIONS_WITH_BUFFER)) {
96 		handle->buf_addr = kalloc_data(max_len, Z_WAITOK | Z_ZERO);
97 		if (!handle->buf_addr) {
98 			kfree_type(ext_paniclog_handle_t, handle);
99 			return NULL;
100 		}
101 	}
102 
103 	memcpy(handle->uuid, uuid, sizeof(uuid_t));
104 	memcpy(handle->data_id, data_id, data_id_size);
105 
106 	handle->options = options;
107 	handle->flags = (options & EXT_PANICLOG_OPTIONS_ADD_SEPARATE_KEY) ? EXT_PANICLOG_FLAGS_ADD_SEPARATE_KEY : EXT_PANICLOG_FLAGS_NONE;
108 	handle->max_len = max_len;
109 	handle->used_len = 0;
110 	handle->active = 0;
111 
112 	return handle;
113 }
114 
115 ext_paniclog_handle_t *
ext_paniclog_handle_alloc_with_buffer(uuid_t uuid,const char * data_id,uint32_t max_len,void * buff,ext_paniclog_create_options_t options)116 ext_paniclog_handle_alloc_with_buffer(uuid_t uuid, const char *data_id,
117     uint32_t max_len, void * buff, ext_paniclog_create_options_t options)
118 {
119 	ext_paniclog_handle_t *handle = NULL;
120 
121 	handle = ext_paniclog_handle_alloc_with_uuid(uuid, data_id, max_len, options);
122 	if (handle == NULL) {
123 		return NULL;
124 	}
125 
126 	handle->buf_addr = buff;
127 
128 	return handle;
129 }
130 
131 void
ext_paniclog_handle_free(ext_paniclog_handle_t * handle)132 ext_paniclog_handle_free(ext_paniclog_handle_t *handle)
133 {
134 	if (handle == NULL) {
135 		return;
136 	}
137 
138 	ext_paniclog_handle_set_inactive(handle);
139 
140 	if (!(handle->options & EXT_PANICLOG_OPTIONS_WITH_BUFFER)) {
141 		kfree_data(handle->buf_addr, handle->max_len);
142 	}
143 
144 	kfree_type(ext_paniclog_handle_t, handle);
145 }
146 
147 int
ext_paniclog_handle_set_active(ext_paniclog_handle_t * handle)148 ext_paniclog_handle_set_active(ext_paniclog_handle_t *handle)
149 {
150 	if (handle == NULL) {
151 		return -1;
152 	}
153 
154 	if (!OSCompareAndSwap8(0, 1, &handle->active)) {
155 		return -1;
156 	}
157 
158 	lck_mtx_lock(&ext_paniclog_list_lock);
159 
160 	LIST_INSERT_HEAD(&ext_paniclog_handle_list, handle, handles);
161 	ext_paniclog_handle_count++;
162 
163 	lck_mtx_unlock(&ext_paniclog_list_lock);
164 
165 	return 0;
166 }
167 
168 int
ext_paniclog_handle_set_inactive(ext_paniclog_handle_t * handle)169 ext_paniclog_handle_set_inactive(ext_paniclog_handle_t *handle)
170 {
171 	if (handle == NULL) {
172 		return -1;
173 	}
174 
175 	if (!OSCompareAndSwap8(1, 0, &handle->active)) {
176 		return -1;
177 	}
178 
179 	lck_mtx_lock(&ext_paniclog_list_lock);
180 
181 	LIST_REMOVE(handle, handles);
182 	ext_paniclog_handle_count--;
183 
184 	lck_mtx_unlock(&ext_paniclog_list_lock);
185 
186 	return 0;
187 }
188 
189 static int
ext_paniclog_insert_data_internal(ext_paniclog_handle_t * handle,void * addr,uint32_t len,uint32_t offset)190 ext_paniclog_insert_data_internal(ext_paniclog_handle_t *handle, void *addr,
191     uint32_t len, uint32_t offset)
192 {
193 	if ((handle == NULL) || (addr == NULL)) {
194 		return -1;
195 	}
196 
197 	if (len > handle->max_len) {
198 		return -1;
199 	}
200 
201 	char *dst = (char *)handle->buf_addr + offset;
202 
203 	memcpy(dst, addr, len);
204 
205 	(void)ext_paniclog_handle_set_active(handle);
206 
207 	return 0;
208 }
209 
210 int
ext_paniclog_insert_data(ext_paniclog_handle_t * handle,void * addr,uint32_t len)211 ext_paniclog_insert_data(ext_paniclog_handle_t *handle, void *addr, uint32_t len)
212 {
213 	int ret = 0;
214 
215 	ret = ext_paniclog_insert_data_internal(handle, addr, len, 0);
216 	if (ret == 0) {
217 		handle->used_len = len;
218 	}
219 
220 	return ret;
221 }
222 
223 int
ext_paniclog_append_data(ext_paniclog_handle_t * handle,void * addr,uint32_t len)224 ext_paniclog_append_data(ext_paniclog_handle_t *handle, void *addr, uint32_t len)
225 {
226 	int ret = 0;
227 	uint32_t updt_len = 0;
228 
229 	if (os_add_overflow(len, handle->used_len, &updt_len)
230 	    || (updt_len > handle->max_len)) {
231 		return -1;
232 	}
233 
234 	ret = ext_paniclog_insert_data_internal(handle, addr, len,
235 	    handle->used_len);
236 	if (ret == 0) {
237 		handle->used_len += len;
238 	}
239 
240 	return ret;
241 }
242 
243 void *
ext_paniclog_claim_buffer(ext_paniclog_handle_t * handle)244 ext_paniclog_claim_buffer(ext_paniclog_handle_t *handle)
245 {
246 	if (handle == NULL) {
247 		return NULL;
248 	}
249 
250 	handle->used_len = handle->max_len;
251 
252 	return handle->buf_addr;
253 }
254 
255 void *
ext_paniclog_get_buffer(ext_paniclog_handle_t * handle)256 ext_paniclog_get_buffer(ext_paniclog_handle_t *handle)
257 {
258 	if (handle == NULL) {
259 		return NULL;
260 	}
261 
262 	return handle->buf_addr;
263 }
264 
265 int
ext_paniclog_set_used_len(ext_paniclog_handle_t * handle,uint32_t used_len)266 ext_paniclog_set_used_len(ext_paniclog_handle_t *handle, uint32_t used_len)
267 {
268 	if (handle == NULL) {
269 		return -1;
270 	}
271 
272 	handle->used_len = used_len;
273 
274 	return 0;
275 }
276 
277 int
ext_paniclog_yield_buffer(ext_paniclog_handle_t * handle,uint32_t used_len)278 ext_paniclog_yield_buffer(ext_paniclog_handle_t *handle, uint32_t used_len)
279 {
280 	return ext_paniclog_set_used_len(handle, used_len);
281 }
282 
283 void
ext_paniclog_panic_with_data(uuid_t uuid,void * addr,uint32_t len)284 ext_paniclog_panic_with_data(uuid_t uuid, void *addr, uint32_t len)
285 {
286 	if (!OSCompareAndSwap8(0, 1, &ext_paniclog_panic_in_progress)) {
287 		return;
288 	}
289 
290 	if (uuid_is_null(uuid)) {
291 		uuid_parse(panic_with_data_uuid, uuid);
292 	}
293 
294 	memcpy(&panic_with_data_handle->uuid[0], &uuid[0], sizeof(uuid_t));
295 
296 	ext_paniclog_insert_data(panic_with_data_handle, addr, len);
297 
298 	return;
299 }
300 
301 static uint32_t
ext_paniclog_get_size_required(void)302 ext_paniclog_get_size_required(void)
303 {
304 	uint32_t size_req = 0;
305 	ext_paniclog_handle_t *tmp;
306 
307 	LIST_FOREACH(tmp, &ext_paniclog_handle_list, handles) {
308 		size_req += (strnlen(tmp->data_id, MAX_DATA_ID_SIZE - 1) + 1) +
309 		    sizeof(ext_paniclog_header_t) + tmp->used_len;
310 	}
311 
312 	// Adding the size of handle count and ext paniclog version variable
313 	size_req += sizeof(ext_paniclog_handle_count) + sizeof(uint32_t);
314 
315 	return size_req;
316 }
317 
318 bool
is_debug_ptr_in_ext_paniclog(void)319 is_debug_ptr_in_ext_paniclog(void)
320 {
321 	bool ext_paniclog_exceeds = ((panic_info->eph_ext_paniclog_offset != 0) ?
322 	    ((uint32_t)(debug_buf_ptr - gPanicBase) >= panic_info->eph_ext_paniclog_offset) :
323 	    false);
324 
325 	return ext_paniclog_exceeds;
326 }
327 
328 /*
329  * Format of the Extensible panic log:
330  *
331  * +---------+------------+---------+---------+------------+------------+---------+---------+---------+-----------+------------+----------+
332  * |         |            |         |         |            |            |         |         |         |           |            |          |
333  * |Version  | No of logs | UUID 1  | Flags 1 | Data ID 1  | Data len 1 | Data 1  | UUID 2  | Flags 2 | Data ID 2 | Data len 2 | Data 2   |
334  * |         |            |         |         |            |            |         |         |         |           |            |          |
335  * +---------+------------+---------+---------+------------+------------+---------+---------+---------+-----------+------------+----------+
336  *
337  */
338 uint32_t
ext_paniclog_write_panicdata(void)339 ext_paniclog_write_panicdata(void)
340 {
341 	ext_paniclog_handle_t *tmp;
342 	char *end = (char *)(debug_buf_base + debug_buf_size);
343 	uint32_t paniclog_buf_size = (uint32_t)(end - debug_buf_ptr);
344 	uint32_t space_left = paniclog_buf_size - OTHER_LOG_REQUIRED_SIZE;
345 	size_t data_id_size = 0;
346 	uint32_t ext_paniclog_version = EXT_PANICLOG_VERSION;
347 	char *dst = NULL;
348 
349 	if (!OSCompareAndSwap8(0, 1, &ext_paniclog_panic_write_done) || (ext_paniclog_handle_count == 0)
350 	    || (paniclog_buf_size < MAX_EXT_PANICLOG_SIZE)) {
351 		return 0;
352 	}
353 
354 	uint32_t size_req = ext_paniclog_get_size_required();
355 
356 	size_req = MIN(MIN(size_req, MAX_EXT_PANICLOG_SIZE), space_left);
357 
358 	dst = (char *)(end - size_req);
359 
360 	memcpy(dst, &ext_paniclog_version, sizeof(ext_paniclog_version));
361 	dst += sizeof(ext_paniclog_version);
362 
363 	memcpy(dst, &ext_paniclog_handle_count, sizeof(ext_paniclog_handle_count));
364 	dst += sizeof(ext_paniclog_handle_count);
365 
366 	LIST_FOREACH(tmp, &ext_paniclog_handle_list, handles) {
367 		data_id_size = strnlen(tmp->data_id, MAX_DATA_ID_SIZE - 1) + 1;
368 
369 		if ((dst + tmp->used_len + data_id_size + sizeof(ext_paniclog_header_t)) > end) {
370 			break;
371 		}
372 
373 		memcpy(dst, tmp->uuid, sizeof(uuid_t));
374 		dst += sizeof(uuid_t);
375 		memcpy(dst, &tmp->flags, sizeof(ext_paniclog_flags_t));
376 		dst += sizeof(ext_paniclog_flags_t);
377 		memcpy(dst, &tmp->data_id, data_id_size);
378 		dst += data_id_size;
379 		memcpy(dst, &tmp->used_len, sizeof(tmp->used_len));
380 		dst += sizeof(tmp->used_len);
381 		memcpy(dst, tmp->buf_addr, tmp->used_len);
382 		dst += tmp->used_len;
383 	}
384 
385 	return size_req;
386 }
387 
388 
389 #if DEVELOPMENT || DEBUG
390 
391 #pragma mark Extensible paniclog tests
392 
393 static int
ext_paniclog_create_multiple_handles(ext_paniclog_handle_t * handles[],const char * data_id[],char * data)394 ext_paniclog_create_multiple_handles(ext_paniclog_handle_t *handles[], const char *data_id[], char *data)
395 {
396 	uuid_t uuid;
397 	uuid_string_t uuid_string;
398 	ext_paniclog_handle_t *handle;
399 
400 	for (int i = 0; i < 2; i++) {
401 		uuid_generate(uuid);
402 		uuid_unparse(uuid, uuid_string);
403 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Creating handle %d with UUID: %s\n", (i + 1), uuid_string);
404 
405 		handle = ext_paniclog_handle_alloc_with_uuid(uuid, data_id[i], 1024, EXT_PANICLOG_OPTIONS_NONE);
406 		if (handle == NULL) {
407 			os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Handle %d is NULL\n", (i + 1));
408 			return -1;
409 		}
410 
411 		handles[i] = handle;
412 
413 		ext_paniclog_insert_data(handle, data, 16);
414 
415 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Used len of buffer: %d\n", handle->used_len);
416 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Data in buffer: %s\n", (char *)ext_paniclog_get_buffer(handle));
417 
418 		ext_paniclog_handle_set_active(handle);
419 	}
420 
421 	return 0;
422 }
423 
424 /*
425  * Test 6: EXT_PANICLOG_TEST_MULTIPLE_HANDLES_PANIC
426  */
427 static int
ext_paniclog_multiple_handles_panic_test(void)428 ext_paniclog_multiple_handles_panic_test(void)
429 {
430 	char data[17] = "abcdefghabcdefgh";
431 	ext_paniclog_handle_t *handles[2] = {0};
432 	const char *data_id[] = {"Test Handle 1", "Test Handle 2"};
433 	uuid_t uuid;
434 	uuid_string_t uuid_string;
435 	uuid_generate(uuid);
436 	uuid_unparse(uuid, uuid_string);
437 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: panic with data UUID: %s", uuid_string);
438 
439 	ext_paniclog_create_multiple_handles(handles, data_id, data);
440 
441 	panic_with_data(uuid, data, 16, "Extensible panic log test");
442 }
443 
444 /*
445  * Test 5: EXT_PANICLOG_TEST_MULTIPLE_HANDLES
446  */
447 static int
ext_paniclog_multiple_handles_test(void)448 ext_paniclog_multiple_handles_test(void)
449 {
450 	char data[17] = "abcdefghabcdefgh";
451 	uint32_t bytes_copied = 0;
452 	uint32_t no_of_logs;
453 	ext_paniclog_flags_t flags;
454 	uint32_t data_len = 0;
455 	ext_paniclog_handle_t *handles[2] = {0};
456 	const char *data_id[] = {"Test Handle 1", "Test Handle 2"};
457 	char *buf_ptr;
458 	int ret = 0;
459 	uint32_t version = 0;
460 
461 	ret = ext_paniclog_create_multiple_handles(handles, data_id, data);
462 	if (ret < 0) {
463 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Create handles failed\n");
464 		return ECANCELED;
465 	}
466 
467 	bytes_copied = ext_paniclog_write_panicdata();
468 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Bytes copied: %d\n", bytes_copied);
469 
470 	buf_ptr = (debug_buf_base + debug_buf_size) - bytes_copied;
471 #if 0
472 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: *****************************************");
473 	for (int i = 0; i < 128; i++) {
474 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: %u ", buf_ptr[i]);
475 	}
476 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: *****************************************");
477 #endif
478 
479 
480 	memcpy(&version, buf_ptr, 4);
481 	if (version != EXT_PANICLOG_VERSION) {
482 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Version mismatch: %d\n", version);
483 		ret = -1;
484 		goto finish;
485 	}
486 
487 	buf_ptr += 4;
488 
489 	memcpy(&no_of_logs, buf_ptr, 4);
490 
491 	if (no_of_logs != 2) {
492 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Num logs is not equal: %d\n", no_of_logs);
493 		ret = -1;
494 		goto finish;
495 	}
496 
497 	buf_ptr = buf_ptr + 20;
498 	for (int i = 1; i >= 0; i--) {
499 		memcpy(&flags, buf_ptr, 4);
500 		if (flags != EXT_PANICLOG_FLAGS_NONE) {
501 			os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Flags are not equal: %d\n", flags);
502 			ret = -1;
503 			goto finish;
504 		}
505 
506 		buf_ptr += 4;
507 
508 		size_t data_id_len = strnlen(data_id[i], MAX_DATA_ID_SIZE);
509 
510 		if (strncmp(data_id[i], buf_ptr, data_id_len)) {
511 			os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: data id is not equal\n");
512 			ret = -1;
513 			goto finish;
514 		}
515 		buf_ptr += data_id_len + 1;
516 		memcpy(&data_len, buf_ptr, 4);
517 
518 		if (data_len != 16) {
519 			os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: data len is not equal: %d\n", data_len);
520 			ret = -1;
521 			goto finish;
522 		}
523 
524 		buf_ptr += 4;
525 
526 		if (memcmp(buf_ptr, data, data_len)) {
527 			os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Buffers don't match\n");
528 			ret = -1;
529 			goto finish;
530 		}
531 
532 		buf_ptr += data_len;
533 		buf_ptr += 16;
534 	}
535 
536 finish:
537 	for (int i = 0; i < 2; i++) {
538 		ext_paniclog_handle_free(handles[i]);
539 	}
540 
541 	return ret;
542 }
543 
544 /*
545  * Test 4: EXT_PANICLOG_TEST_WRITE_PANIC_DATA
546  */
547 static int
ext_paniclog_write_panicdata_test(void)548 ext_paniclog_write_panicdata_test(void)
549 {
550 	uuid_t uuid;
551 	uuid_generate(uuid);
552 	uuid_string_t uuid_string;
553 	uuid_unparse(uuid, uuid_string);
554 	uint32_t bytes_copied;
555 	const char data_id[] = "Test Handle";
556 	char *buf_ptr;
557 	uint32_t num_of_logs = 0;
558 	ext_paniclog_flags_t flags;
559 	uint32_t data_len = 0;
560 	char data1[17] = "abcdefghabcdefgh";
561 	char panic_data[1024] = {0};
562 	uint32_t version = 0;
563 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Creating handle with UUID: %s\n", uuid_string);
564 
565 	// Including ADD_SEPARATE_KEY option allows us to test if the option --> flag translation works well
566 	ext_paniclog_handle_t *handle = ext_paniclog_handle_alloc_with_uuid(uuid, data_id, 1024, EXT_PANICLOG_OPTIONS_ADD_SEPARATE_KEY);
567 	if (handle == NULL) {
568 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Handle is NULL\n");
569 		return ECANCELED;
570 	}
571 
572 	ext_paniclog_insert_data(handle, data1, 16);
573 
574 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Used len of buffer: %d\n", handle->used_len);
575 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Data in buffer: %s\n", (char *)ext_paniclog_get_buffer(handle));
576 
577 	ext_paniclog_handle_set_active(handle);
578 
579 	bytes_copied = ext_paniclog_write_panicdata();
580 
581 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Bytes copied: %d\n", bytes_copied);
582 
583 	buf_ptr = (debug_buf_base + debug_buf_size) - bytes_copied;
584 #if 0
585 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: *****************************************");
586 	for (int i = 0; i < 100; i++) {
587 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: %u ", panic_data[i]);
588 	}
589 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: *****************************************");
590 #endif
591 
592 	memcpy(&version, buf_ptr, 4);
593 	if (version != EXT_PANICLOG_VERSION) {
594 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Version mismatch: %d\n", version);
595 		ext_paniclog_handle_free(handle);
596 		return ECANCELED;
597 	}
598 
599 	buf_ptr += 4;
600 
601 	memcpy(&num_of_logs, buf_ptr, 4);
602 
603 	if (num_of_logs != 1) {
604 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Num logs is not equal: %d\n", num_of_logs);
605 		ext_paniclog_handle_free(handle);
606 		return ECANCELED;
607 	}
608 
609 	buf_ptr += 4;
610 
611 	char *uuid_cmp = (char *)(buf_ptr);
612 
613 	if (memcmp(uuid_cmp, uuid, 16)) {
614 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: UUID is not equal\n");
615 		ext_paniclog_handle_free(handle);
616 		return ECANCELED;
617 	}
618 
619 	buf_ptr += 16;
620 
621 	memcpy(&flags, buf_ptr, 4);
622 
623 	if (!(flags & EXT_PANICLOG_FLAGS_ADD_SEPARATE_KEY)) {
624 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Flags are not equal: %d\n", flags);
625 		ext_paniclog_handle_free(handle);
626 		return ECANCELED;
627 	}
628 
629 	buf_ptr += 4;
630 
631 	size_t data_id_len = strnlen(data_id, MAX_DATA_ID_SIZE);
632 
633 	if (strncmp(data_id, buf_ptr, data_id_len)) {
634 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: data id is not equal: %s\n", panic_data + 20);
635 		ext_paniclog_handle_free(handle);
636 		return ECANCELED;
637 	}
638 
639 	buf_ptr += data_id_len + 1;
640 	memcpy(&data_len, buf_ptr, 4);
641 
642 	if (data_len != 16) {
643 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: data len is not equal: %d\n", data_len);
644 		ext_paniclog_handle_free(handle);
645 		return ECANCELED;
646 	}
647 
648 	buf_ptr += 4;
649 	char *data_cmp = (char *)(buf_ptr);
650 
651 	if (memcmp(data_cmp, data1, data_len)) {
652 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Buffers don't match\n");
653 		ext_paniclog_handle_free(handle);
654 		return ECANCELED;
655 	}
656 
657 	ext_paniclog_handle_free(handle);
658 
659 	return 0;
660 }
661 
662 /*
663  * Test 1: EXT_PANICLOG_TEST_HANDLE_CREATE
664  */
665 static int
ext_paniclog_handle_create_test(void)666 ext_paniclog_handle_create_test(void)
667 {
668 	uint32_t max_len = 1024;
669 	uuid_t uuid;
670 	uuid_generate(uuid);
671 	uuid_string_t uuid_string;
672 	uuid_unparse(uuid, uuid_string);
673 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Creating handle with UUID: %s\n", uuid_string);
674 
675 	ext_paniclog_handle_t *handle = ext_paniclog_handle_alloc_with_uuid(uuid, "Test Handle", max_len, EXT_PANICLOG_OPTIONS_NONE);
676 	if (handle == NULL) {
677 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Handle create failed. Returned NULL\n");
678 		return ECANCELED;
679 	}
680 
681 	if ((strncmp(handle->data_id, "Test Handle", strlen(handle->data_id))) ||
682 	    (handle->max_len != 1024)) {
683 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: attribute mismatch\n");
684 		ext_paniclog_handle_free(handle);
685 		return ECANCELED;
686 	}
687 
688 	ext_paniclog_handle_free(handle);
689 
690 	return 0;
691 }
692 
693 static int
ext_paniclog_get_list_count(void)694 ext_paniclog_get_list_count(void)
695 {
696 	int cnt = 0;
697 	ext_paniclog_handle_t *tmp;
698 
699 	lck_mtx_lock(&ext_paniclog_list_lock);
700 
701 	LIST_FOREACH(tmp, &ext_paniclog_handle_list, handles) {
702 		if (tmp != NULL) {
703 			cnt++;
704 		}
705 	}
706 
707 	lck_mtx_unlock(&ext_paniclog_list_lock);
708 
709 	return cnt;
710 }
711 
712 /*
713  * Test 2: EXT_PANICLOG_TEST_SET_ACTIVE_INACTIVE
714  */
715 static int
ext_paniclog_set_active_inactive_test(void)716 ext_paniclog_set_active_inactive_test(void)
717 {
718 	uuid_t uuid;
719 	uuid_generate(uuid);
720 	uuid_string_t uuid_string;
721 	uuid_unparse(uuid, uuid_string);
722 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Creating handle with UUID: %s\n", uuid_string);
723 
724 	ext_paniclog_handle_t *handle = ext_paniclog_handle_alloc_with_uuid(uuid, "Test handle", 1024, EXT_PANICLOG_OPTIONS_NONE);
725 
726 	int cnt = 0;
727 	int initial_cnt = ext_paniclog_get_list_count();
728 
729 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Initial list count: %d\n", initial_cnt);
730 
731 	ext_paniclog_handle_set_active(handle);
732 
733 	cnt = ext_paniclog_get_list_count();
734 
735 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: List count after active: %d\n", cnt);
736 
737 	if (cnt != (initial_cnt + 1)) {
738 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: List count error after active\n");
739 		ext_paniclog_handle_free(handle);
740 		return ECANCELED;
741 	}
742 
743 	ext_paniclog_handle_set_inactive(handle);
744 
745 	cnt = ext_paniclog_get_list_count();
746 
747 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: List count after inactive: %d\n", cnt);
748 
749 	if (cnt != initial_cnt) {
750 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: List count error after inactive\n");
751 		ext_paniclog_handle_free(handle);
752 		return ECANCELED;
753 	}
754 
755 	ext_paniclog_handle_free(handle);
756 
757 	return 0;
758 }
759 
760 /*
761  * Test 3: EXT_PANICLOG_TEST_INSERT_DATA
762  */
763 static int
ext_paniclog_insert_data_test(void)764 ext_paniclog_insert_data_test(void)
765 {
766 	uuid_t uuid;
767 	uuid_generate(uuid);
768 	uuid_string_t uuid_string;
769 	uuid_unparse(uuid, uuid_string);
770 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Creating handle with UUID: %s\n", uuid_string);
771 
772 	ext_paniclog_handle_t *handle = ext_paniclog_handle_alloc_with_uuid(uuid, "Test handle", 1024, EXT_PANICLOG_OPTIONS_NONE);
773 
774 	char data1[9] = "abcdefgh";
775 
776 	ext_paniclog_insert_data(handle, data1, 8);
777 
778 	if (memcmp(handle->buf_addr, data1, 8)) {
779 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Buffers don't match\n");
780 		ext_paniclog_handle_free(handle);
781 		return ECANCELED;
782 	}
783 
784 	char data2[9] = "abcdefgh";
785 	char cmp_data[17] = "abcdefghabcdefgh";
786 
787 	ext_paniclog_append_data(handle, data2, 8);
788 
789 	if (memcmp(handle->buf_addr, cmp_data, 16)) {
790 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Buffers don't match\n");
791 		ext_paniclog_handle_free(handle);
792 		return ECANCELED;
793 	}
794 
795 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Used len of buffer: %d\n", handle->used_len);
796 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Data in buffer: %s\n", (char *)ext_paniclog_get_buffer(handle));
797 
798 	ext_paniclog_handle_free(handle);
799 
800 	return 0;
801 }
802 
803 /* Test 7 */
804 static int
ext_paniclog_insert_dummy_handles_test(void)805 ext_paniclog_insert_dummy_handles_test(void)
806 {
807 	ext_paniclog_handle_t *handle_1, *handle_2, *handle_3;
808 	char data1[18] = "Data for handle 1";
809 	char data2[18] = "Data for handle 2";
810 	char data3[18] = "Data for handle 3";
811 
812 	char uuid_string_1[] = "28245A8F-04CA-4932-8A38-E6C159FD9C92";
813 	uuid_t uuid_1;
814 	uuid_parse(uuid_string_1, uuid_1);
815 	handle_1 = ext_paniclog_handle_alloc_with_uuid(uuid_1, "Dummy handle 1", 1024, EXT_PANICLOG_OPTIONS_NONE);
816 	if (handle_1 == NULL) {
817 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Failed to create handle 1\n");
818 		return ECANCELED;
819 	}
820 
821 	handle_2 = ext_paniclog_handle_alloc_with_uuid(uuid_1, "Dummy handle 2", 1024, EXT_PANICLOG_OPTIONS_NONE);
822 	if (handle_2 == NULL) {
823 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Failed to create handle 2\n");
824 		return ECANCELED;
825 	}
826 
827 	char uuid_string_3[] = "A10F32F8-D5AF-431F-8098-FEDD0FFB794A";
828 	uuid_t uuid_3;
829 	uuid_parse(uuid_string_3, uuid_3);
830 	handle_3 = ext_paniclog_handle_alloc_with_uuid(uuid_3, "Dummy handle 3", 1024, EXT_PANICLOG_OPTIONS_NONE);
831 	if (handle_3 == NULL) {
832 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Failed to create handle 3\n");
833 		return ECANCELED;
834 	}
835 
836 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Created three handles\n");
837 
838 	ext_paniclog_insert_data(handle_1, data1, 17);
839 	ext_paniclog_insert_data(handle_2, data2, 17);
840 	ext_paniclog_insert_data(handle_3, data3, 17);
841 
842 	ext_paniclog_handle_set_active(handle_1);
843 	ext_paniclog_handle_set_active(handle_2);
844 	ext_paniclog_handle_set_active(handle_3);
845 
846 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Inserted three handles\n");
847 
848 	return 0;
849 }
850 
851 /* Test 8 */
852 static int
ext_paniclog_insert_struct_handles_test(void)853 ext_paniclog_insert_struct_handles_test(void)
854 {
855 	ext_paniclog_handle_t *handle_1, *handle_2;
856 	struct _handle_1_data {
857 		uint32_t dummy_1;
858 		uint32_t dummy_2;
859 		uint32_t dummy_3;
860 	};
861 
862 	struct _handle_2_data {
863 		uint32_t dummy_1;
864 		uint32_t dummy_2;
865 	};
866 
867 	struct _handle_1_data *handle_1_data;
868 	struct _handle_2_data *handle_2_data;
869 
870 	char uuid_string_1[] = "938371FB-3B47-415E-B766-743DE6D44E6E";
871 	uuid_t uuid_1;
872 	uuid_parse(uuid_string_1, uuid_1);
873 	handle_1 = ext_paniclog_handle_alloc_with_uuid(uuid_1, "Dummy handle 1", 1024, EXT_PANICLOG_OPTIONS_NONE);
874 	if (handle_1 == NULL) {
875 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Failed to create handle 1\n");
876 		return ECANCELED;
877 	}
878 
879 	char uuid_string_2[] = "78FD5A06-1FA3-4B1C-A2F5-AF82F5D9CEFD";
880 	uuid_t uuid_2;
881 	uuid_parse(uuid_string_2, uuid_2);
882 
883 	handle_2 = ext_paniclog_handle_alloc_with_uuid(uuid_2, "Dummy handle 2", 1024, EXT_PANICLOG_OPTIONS_NONE);
884 	if (handle_2 == NULL) {
885 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Failed to create handle 3\n");
886 		return ECANCELED;
887 	}
888 
889 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Created two handles\n");
890 
891 	handle_1_data = (struct _handle_1_data *)ext_paniclog_claim_buffer(handle_1);
892 
893 	handle_2_data = (struct _handle_2_data *)ext_paniclog_claim_buffer(handle_2);
894 
895 	handle_1_data->dummy_1 = 0x1000;
896 	handle_1_data->dummy_2 = 0xFFFFFFFF;
897 	handle_1_data->dummy_3 = 0x65;
898 
899 	handle_2_data->dummy_1 = 0x10000000;
900 	handle_2_data->dummy_2 = 0xFFFF;
901 
902 	ext_paniclog_yield_buffer(handle_1, sizeof(struct _handle_1_data));
903 	ext_paniclog_yield_buffer(handle_2, sizeof(struct _handle_2_data));
904 
905 	ext_paniclog_handle_set_active(handle_1);
906 	ext_paniclog_handle_set_active(handle_2);
907 
908 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Wrote two handles\n");
909 
910 	return 0;
911 }
912 
913 /*
914  * Test 9
915  * Insert one handle with string data and one handle with struct data
916  * into the ext_paniclog with the "ADD_SEPARATE_KEY" flag so that they're
917  * added as separate fields in the paniclog.
918  */
919 static int
ext_paniclog_insert_dummy_handles_separate_fields_test(void)920 ext_paniclog_insert_dummy_handles_separate_fields_test(void)
921 {
922 	ext_paniclog_handle_t *handle_1, *handle_2;
923 	char data1[18] = "Data for handle 1";
924 
925 	struct _handle_2_data {
926 		uint32_t dummy_1;
927 		uint32_t dummy_2;
928 	};
929 
930 	struct _handle_2_data *handle_2_data;
931 
932 	char uuid_string_1[] = "28245A8F-04CA-4932-8A38-E6C159FD9C92";
933 	uuid_t uuid_1;
934 	uuid_parse(uuid_string_1, uuid_1);
935 	handle_1 = ext_paniclog_handle_alloc_with_uuid(uuid_1, "Dummy handle 1", 1024, EXT_PANICLOG_OPTIONS_ADD_SEPARATE_KEY);
936 	if (handle_1 == NULL) {
937 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Failed to create handle 1\n");
938 		return ECANCELED;
939 	}
940 
941 	char uuid_string_2[] = "A10F32F8-D5AF-431F-8098-FEDD0FFB794A";
942 	uuid_t uuid_2;
943 	uuid_parse(uuid_string_2, uuid_2);
944 
945 	handle_2 = ext_paniclog_handle_alloc_with_uuid(uuid_2, "Dummy handle 2", 1024, EXT_PANICLOG_OPTIONS_ADD_SEPARATE_KEY);
946 	if (handle_2 == NULL) {
947 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Failed to create handle 2\n");
948 		return ECANCELED;
949 	}
950 
951 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Created two handles\n");
952 
953 	// Insert handle with string data
954 	ext_paniclog_insert_data(handle_1, data1, 17);
955 
956 	// Insert handle with struct data
957 	handle_2_data = (struct _handle_2_data *)ext_paniclog_claim_buffer(handle_2);
958 	handle_2_data->dummy_1 = 0x10000000;
959 	handle_2_data->dummy_2 = 0xFFFF;
960 	ext_paniclog_yield_buffer(handle_2, sizeof(struct _handle_2_data));
961 
962 	ext_paniclog_handle_set_active(handle_1);
963 	ext_paniclog_handle_set_active(handle_2);
964 
965 	os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Inserted two handles\n");
966 
967 	return 0;
968 }
969 
970 int
ext_paniclog_test_hook(uint32_t option)971 ext_paniclog_test_hook(uint32_t option)
972 {
973 	int rval = 0;
974 
975 	switch (option) {
976 	case EXT_PANICLOG_TEST_HANDLE_CREATE:
977 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Create handle test\n");
978 		rval = ext_paniclog_handle_create_test();
979 		break;
980 	case EXT_PANICLOG_TEST_SET_ACTIVE_INACTIVE:
981 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Testing set active and inactive\n");
982 		rval = ext_paniclog_set_active_inactive_test();
983 		break;
984 	case EXT_PANICLOG_TEST_INSERT_DATA:
985 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Testing insert data\n");
986 		rval = ext_paniclog_insert_data_test();
987 		break;
988 	case EXT_PANICLOG_TEST_WRITE_PANIC_DATA:
989 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Testing panic data write\n");
990 		rval = ext_paniclog_write_panicdata_test();
991 		break;
992 	case EXT_PANICLOG_TEST_MULTIPLE_HANDLES:
993 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Testing multiple handles\n");
994 		rval = ext_paniclog_multiple_handles_test();
995 		break;
996 	case EXT_PANICLOG_TEST_MULTIPLE_HANDLES_PANIC:
997 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Testing multiple handles with panic\n");
998 		rval = ext_paniclog_multiple_handles_panic_test();
999 		break;
1000 	case EXT_PANICLOG_TEST_INSERT_DUMMY_HANDLES:
1001 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Insert dummy handles\n");
1002 		rval = ext_paniclog_insert_dummy_handles_test();
1003 		break;
1004 	case EXT_PANICLOG_TEST_INSERT_STRUCT_HANDLES:
1005 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Insert struct handles\n");
1006 		rval = ext_paniclog_insert_struct_handles_test();
1007 		break;
1008 	case EXT_PANICLOG_TEST_INSERT_DUMMY_HANDLES_AS_SEPARATE_FIELDS:
1009 		os_log(OS_LOG_DEFAULT, "EXT_PANICLOG_TEST: Insert dummy handles as separate fields\n");
1010 		rval = ext_paniclog_insert_dummy_handles_separate_fields_test();
1011 		break;
1012 	default:
1013 		os_log(OS_LOG_DEFAULT, "Not a valid option\n");
1014 		break;
1015 	}
1016 
1017 	if (rval != 0) {
1018 		printf("EXT_PANICLOG_TEST: Test Failed with error code: %d\n", rval);
1019 	} else {
1020 		printf("EXT_PANICLOG_TEST: Test Success\n");
1021 	}
1022 	return rval;
1023 }
1024 #endif // DEVELOPEMNT || DEBUG
1025 
1026 #else // CONFIG_EXT_PANICLOG
1027 
1028 /*
1029  * All ext paniclog functions which fail when CONFIG_EXT_PANICLOG is not
1030  * enabled.
1031  */
1032 
1033 void
ext_paniclog_init(void)1034 ext_paniclog_init(void)
1035 {
1036 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1037 	return;
1038 }
1039 
1040 ext_paniclog_handle_t *
ext_paniclog_handle_alloc_with_uuid(uuid_t uuid __unused,const char * data_id __unused,uint32_t max_len __unused,ext_paniclog_create_options_t options __unused)1041 ext_paniclog_handle_alloc_with_uuid(uuid_t uuid __unused, const char *data_id __unused,
1042     uint32_t max_len __unused, ext_paniclog_create_options_t options __unused)
1043 {
1044 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1045 	return NULL;
1046 }
1047 
1048 ext_paniclog_handle_t *
ext_paniclog_handle_alloc_with_buffer(uuid_t uuid __unused,const char * data_id __unused,uint32_t max_len __unused,void * buff __unused,ext_paniclog_create_options_t options __unused)1049 ext_paniclog_handle_alloc_with_buffer(uuid_t uuid __unused, const char *data_id __unused,
1050     uint32_t max_len __unused, void * buff __unused, ext_paniclog_create_options_t options __unused)
1051 {
1052 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1053 	return NULL;
1054 }
1055 
1056 void
ext_paniclog_handle_free(ext_paniclog_handle_t * handle __unused)1057 ext_paniclog_handle_free(ext_paniclog_handle_t *handle __unused)
1058 {
1059 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1060 	return;
1061 }
1062 
1063 int
ext_paniclog_handle_set_active(ext_paniclog_handle_t * handle __unused)1064 ext_paniclog_handle_set_active(ext_paniclog_handle_t *handle __unused)
1065 {
1066 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1067 	return -1;
1068 }
1069 
1070 int
ext_paniclog_handle_set_inactive(ext_paniclog_handle_t * handle __unused)1071 ext_paniclog_handle_set_inactive(ext_paniclog_handle_t *handle __unused)
1072 {
1073 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1074 	return -1;
1075 }
1076 
1077 int
ext_paniclog_insert_data(ext_paniclog_handle_t * handle __unused,void * addr __unused,uint32_t len __unused)1078 ext_paniclog_insert_data(ext_paniclog_handle_t *handle __unused, void *addr __unused, uint32_t len __unused)
1079 {
1080 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1081 	return -1;
1082 }
1083 
1084 int
ext_paniclog_append_data(ext_paniclog_handle_t * handle __unused,void * addr __unused,uint32_t len __unused)1085 ext_paniclog_append_data(ext_paniclog_handle_t *handle __unused, void *addr __unused, uint32_t len __unused)
1086 {
1087 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1088 	return -1;
1089 }
1090 
1091 void *
ext_paniclog_claim_buffer(ext_paniclog_handle_t * handle __unused)1092 ext_paniclog_claim_buffer(ext_paniclog_handle_t *handle __unused)
1093 {
1094 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1095 	return NULL;
1096 }
1097 
1098 void *
ext_paniclog_get_buffer(ext_paniclog_handle_t * handle __unused)1099 ext_paniclog_get_buffer(ext_paniclog_handle_t *handle __unused)
1100 {
1101 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1102 	return NULL;
1103 }
1104 
1105 int
ext_paniclog_set_used_len(ext_paniclog_handle_t * handle __unused,uint32_t used_len __unused)1106 ext_paniclog_set_used_len(ext_paniclog_handle_t *handle __unused, uint32_t used_len __unused)
1107 {
1108 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1109 	return -1;
1110 }
1111 
1112 int
ext_paniclog_yield_buffer(ext_paniclog_handle_t * handle __unused,uint32_t used_len __unused)1113 ext_paniclog_yield_buffer(ext_paniclog_handle_t *handle __unused, uint32_t used_len __unused)
1114 {
1115 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1116 	return -1;
1117 }
1118 
1119 void
ext_paniclog_panic_with_data(uuid_t uuid __unused,void * addr __unused,uint32_t len __unused)1120 ext_paniclog_panic_with_data(uuid_t uuid __unused, void *addr __unused, uint32_t len __unused)
1121 {
1122 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1123 	return;
1124 }
1125 
1126 bool
is_debug_ptr_in_ext_paniclog(void)1127 is_debug_ptr_in_ext_paniclog(void)
1128 {
1129 	return false;
1130 }
1131 
1132 uint32_t
ext_paniclog_write_panicdata(void)1133 ext_paniclog_write_panicdata(void)
1134 {
1135 	os_log_error(OS_LOG_DEFAULT, "Extensible paniclog not supported");
1136 	return 0;
1137 }
1138 #endif // CONFIG_EXT_PANICLOG
1139