+static inline void
+_libSystem_ktrace4(uint32_t code, uint64_t a, uint64_t b, uint64_t c, uint64_t d)
+{
+ if (__builtin_expect(*(volatile uint32_t *)_COMM_PAGE_KDEBUG_ENABLE == 0, 1)) return;
+ kdebug_trace(code, a, b, c, d);
+}
+#define _libSystem_ktrace3(code, a, b, c) _libSystem_ktrace4(code, a, b, c, 0)
+#define _libSystem_ktrace2(code, a, b) _libSystem_ktrace4(code, a, b, 0, 0)
+#define _libSystem_ktrace1(code, a) _libSystem_ktrace4(code, a, 0, 0, 0)
+#define _libSystem_ktrace0(code) _libSystem_ktrace4(code, 0, 0, 0, 0)
+
+/*
+ * these define stable Ariadne tracepoints. If initializers are removed, or
+ * added, then old tracepoints MUST NOT be recycled.
+ */
+enum {
+ ARIADNE_LIFECYCLE_libsystem_init = ARIADNEDBG_CODE(220, 4),
+};
+
+/*
+ * These represent the initializer "name"
+ *
+ * They happen to match the order of the initializers at some point in time,
+ * but there's no guarantee made that traecepoints will appear in numerical
+ * order. As initializers come and go, new codes shall be allocated,
+ * and no slots reused.
+ */
+enum init_func {
+ INIT_SYSTEM = 0,
+ INIT_KERNEL = 1,
+ INIT_PLATFORM = 2,
+ INIT_PTHREAD = 3,
+ INIT_LIBC = 4,
+ INIT_MALLOC = 5,
+ INIT_KEYMGR = 6,
+ INIT_DYLD = 7,
+ INIT_LIBDISPATCH = 8,
+ INIT_LIBXPC = 9,
+ INIT_LIBTRACE = 10,
+ INIT_SECINIT = 11,
+ INIT_CONTAINERMGR = 12,
+ INIT_DARWIN = 13,
+};
+
+#define _libSystem_ktrace_init_func(what) \
+ _libSystem_ktrace1(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_NONE, INIT_##what)
+