]>
git.saurik.com Git - apple/xnu.git/blob - tests/preoslog.c
9b1b26141b6513170dd88678ffdcf817b56feff7
1 #include <darwintest.h>
2 #include <darwintest_utils.h>
3 #include <sys/sysctl.h>
7 #include "test_utils.h"
10 * Any change to this structure must be reflected in iBoot / MacEFI / PanicDump / XNU Tests and vice versa.
12 typedef struct __attribute__((packed
)) {
13 uint32_t magic
; /* g_valid_magic if valid */
14 uint32_t size
; /* Size of the preoslog buffer including the header */
15 uint32_t offset
; /* Write pointer. Indicates where in the buffer new log entry would go */
16 uint8_t source
; /* Indicates who filled in the buffer (e.g. iboot vs MacEFI) */
17 uint8_t wrapped
; /* If equal to 1, the preoslog ring buffer wrapped at least once */
18 char data
[]; /* log buffer */
21 static const char* g_sysctl_kern_version
= "kern.version";
22 static const char* g_sysctl_kern_preoslog
= "kern.preoslog";
23 static const uint32_t g_valid_magic
= 'LSOP';
26 * Defines substrings to look up in preoslog buffer.
27 * To pass the test, one of the entries should match a substring in preoslog buffer.
29 static const char* g_preoslog_buffer_string
[] = {"serial output"};
32 check_for_substrings(const char* string
, size_t len
)
35 boolean_t res
= FALSE
;
37 for (i
= 0; i
< (sizeof(g_preoslog_buffer_string
) / sizeof(char*)); i
++) {
38 res
= res
|| strnstr(string
, g_preoslog_buffer_string
[i
], len
) == NULL
? FALSE
: TRUE
;
46 * 1. Development & Debug iBoot/macEFI provides a preoslog buffer.
47 * 2. Release iBoot/macEFI doesn't provide a presoslog buffer.
48 * 3. Development & Debug xnu provids kern.preoslog sysctl.
49 * 4. Release xnu doesn't provide kern.preoslog sysctl.
52 T_DECL(test_preoslog
, "Validate kern.preoslog sysctl has expected log content from the boot loader")
57 preoslog_header_t
*header
= NULL
;
59 const char *lower_buffer
= NULL
;
60 size_t lower_buffer_size
= 0;
61 const char *upper_buffer
= NULL
;
62 size_t upper_buffer_size
= 0;
63 boolean_t found
= FALSE
;
65 // kern.preoslog is writable
66 ret
= sysctlbyname(g_sysctl_kern_preoslog
, buffer
, &size
, &tmp
, sizeof(tmp
));
67 T_ASSERT_POSIX_SUCCESS(ret
, "kern.preoslog write check");
69 ret
= sysctlbyname(g_sysctl_kern_preoslog
, NULL
, &size
, NULL
, 0);
70 if (!is_development_kernel()) {
71 // kern.preoslog mustn't exist on release builds of xnu
72 T_ASSERT_NE(ret
, 0, "get size kern.preoslog ret != 0 on release builds");
73 T_ASSERT_POSIX_ERROR(ret
, ENOENT
, " get size kern.preoslog errno==ENOENT on release builds");
78 * Everything below is applicable only to development & debug xnu
81 T_ASSERT_POSIX_SUCCESS(ret
, "get size for kern.preoslog");
83 // No preoslog buffer available, valid case if iboot is release
87 buffer
= calloc(size
, sizeof(char));
88 T_ASSERT_NOTNULL(buffer
, "allocate buffer for preoslog");
90 ret
= sysctlbyname(g_sysctl_kern_preoslog
, buffer
, &size
, NULL
, 0);
91 T_ASSERT_POSIX_SUCCESS(ret
, "get preoslog buffer");
93 header
= (preoslog_header_t
*)buffer
;
94 T_ASSERT_EQ(header
->magic
, g_valid_magic
, "check preoslog header magic - expected %#x, given %#x", g_valid_magic
, header
->magic
);
95 T_ASSERT_EQ(header
->size
, size
, "check preoslog sizes - expected %zu, given %zu", size
, header
->size
);
96 T_ASSERT_LT(header
->offset
, header
->size
- sizeof(*header
), "check write offset");
98 lower_buffer
= header
->data
;
99 lower_buffer_size
= header
->offset
+ 1;
100 upper_buffer
= lower_buffer
+ lower_buffer_size
;
101 upper_buffer_size
= header
->size
- lower_buffer_size
- sizeof(*header
);
102 if (header
->wrapped
) {
103 found
= check_for_substrings(upper_buffer
, upper_buffer_size
);
106 found
= found
|| check_for_substrings(lower_buffer
, lower_buffer_size
);
107 T_ASSERT_TRUE(found
, "Verify buffer content");