--- /usr/include/os/trace.h	2016-02-27 01:01:41.000000000 -0500
+++ trace.h	2016-10-24 00:19:18.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2013-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -30,6 +30,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdarg.h>
+#include <mach-o/loader.h>
 #if __has_include(<xpc/xpc.h>)
 #include <xpc/xpc.h>
 #else
@@ -40,395 +41,86 @@
 #error "must be GNU C compatible"
 #endif
 
-extern void *__dso_handle;
+__BEGIN_DECLS
 
-OS_ALWAYS_INLINE
-static inline void
-_os_trace_verify_printf(const char *msg, ...) __attribute__((format(printf, 1, 2)))
-{
-#pragma unused(msg)
-}
+extern struct mach_header __dso_handle;
 
 #if !defined OS_COUNT_ARGS
 #define OS_COUNT_ARGS(...) OS_COUNT_ARGS1(, ##__VA_ARGS__, _8, _7, _6, _5, _4, _3, _2, _1, _0)
 #define OS_COUNT_ARGS1(z, a, b, c, d, e, f, g, h, cnt, ...) cnt
 #endif
 
-#define _os_trace_0(_l, _m, _t) __extension__({ \
-	_os_trace_verify_printf(_l); \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, NULL, 0, NULL); \
-	__asm__(""); /* avoid tailcall */ \
-})
-
-#define _os_trace_1(_l, _m, _t, _1) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	_os_trace_verify_printf(_l, _c1); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		unsigned char _s[2]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._s[1] = 1, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), NULL); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
-
-#define _os_trace_2(_l, _m, _t, _1, _2) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	_os_trace_verify_printf(_l, _c1, _c2); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		unsigned char _s[3]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._s[2] = 2, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), NULL); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
-
-#define _os_trace_3(_l, _m, _t, _1, _2, _3) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		unsigned char _s[4]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._s[3] = 3, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), NULL); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
-
-#define _os_trace_4(_l, _m, _t, _1, _2, _3, _4) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	const __typeof__(_4) _c4 = _4; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3, _c4); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		__typeof__(_c4) _f4; \
-		unsigned char _s[5]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._f4 = _c4, ._s[3] = sizeof(_c4), \
-		._s[4] = 4, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), NULL); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
-
-#define _os_trace_5(_l, _m, _t, _1, _2, _3, _4, _5) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	const __typeof__(_4) _c4 = _4; \
-	const __typeof__(_5) _c5 = _5; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3, _c4, _c5); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		__typeof__(_c4) _f4; \
-		__typeof__(_c5) _f5; \
-		unsigned char _s[6]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._f4 = _c4, ._s[3] = sizeof(_c4), \
-		._f5 = _c5, ._s[4] = sizeof(_c5), \
-		._s[5] = 5, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), NULL); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
-
-#define _os_trace_6(_l, _m, _t, _1, _2, _3, _4, _5, _6) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	const __typeof__(_4) _c4 = _4; \
-	const __typeof__(_5) _c5 = _5; \
-	const __typeof__(_6) _c6 = _6; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3, _c4, _c5, _c6); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		__typeof__(_c4) _f4; \
-		__typeof__(_c5) _f5; \
-		__typeof__(_c6) _f6; \
-		unsigned char _s[7]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._f4 = _c4, ._s[3] = sizeof(_c4), \
-		._f5 = _c5, ._s[4] = sizeof(_c5), \
-		._f6 = _c6, ._s[5] = sizeof(_c6), \
-		._s[6] = 6, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), NULL); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
-
-#define _os_trace_7(_l, _m, _t, _1, _2, _3, _4, _5, _6, _7) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	const __typeof__(_4) _c4 = _4; \
-	const __typeof__(_5) _c5 = _5; \
-	const __typeof__(_6) _c6 = _6; \
-	const __typeof__(_7) _c7 = _7; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3, _c4, _c5, _c6, _c7); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		__typeof__(_c4) _f4; \
-		__typeof__(_c5) _f5; \
-		__typeof__(_c6) _f6; \
-		__typeof__(_c7) _f7; \
-		unsigned char _s[8]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._f4 = _c4, ._s[3] = sizeof(_c4), \
-		._f5 = _c5, ._s[4] = sizeof(_c5), \
-		._f6 = _c6, ._s[5] = sizeof(_c6), \
-		._f7 = _c7, ._s[6] = sizeof(_c7), \
-		._s[7] = 7, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), NULL); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
-
-#define _os_trace_with_payload_1(_l, _m, _t, _payload) __extension__({ \
-	_os_trace_verify_printf(_l); \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, NULL, 0, _payload); \
-	__asm__(""); /* avoid tailcall */ \
-})
-
-#define _os_trace_with_payload_2(_l, _m, _t, _1, _payload) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	_os_trace_verify_printf(_l, _c1); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		unsigned char _s[2]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._s[1] = 1, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), _payload); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
-
-#define _os_trace_with_payload_3(_l, _m, _t, _1, _2, _payload) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	_os_trace_verify_printf(_l, _c1, _c2); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		unsigned char _s[3]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._s[2] = 2, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), _payload); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
+static inline void
+_os_trace_verify_printf(const char *msg, ...) __attribute__((format(os_trace, 1, 2)));
 
-#define _os_trace_with_payload_4(_l, _m, _t, _1, _2, _3, _payload) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		unsigned char _s[4]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._s[3] = 3, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), _payload); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
+OS_ALWAYS_INLINE
+static inline void
+_os_trace_verify_printf(const char *msg, ...)
+{
+#pragma unused(msg)
+}
 
-#define _os_trace_with_payload_5(_l, _m, _t, _1, _2, _3, _4, _payload) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	const __typeof__(_4) _c4 = _4; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3, _c4); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		__typeof__(_c4) _f4; \
-		unsigned char _s[5]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._f4 = _c4, ._s[3] = sizeof(_c4), \
-		._s[4] = 4, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), _payload); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
+/* We need at least clang 7.3 or later due to bugs in os_log_format parsing */
+#if __has_builtin(__builtin_os_log_format) && (__clang_major__ > 7 || (__clang_major__ == 7 && __clang_minor__ >= 3))
 
-#define _os_trace_with_payload_6(_l, _m, _t, _1, _2, _3, _4, _5, _payload) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	const __typeof__(_4) _c4 = _4; \
-	const __typeof__(_4) _c5 = _5; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3, _c4, _c5); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		__typeof__(_c4) _f4; \
-		__typeof__(_c5) _f5; \
-		unsigned char _s[6]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._f4 = _c4, ._s[3] = sizeof(_c4), \
-		._f5 = _c5, ._s[4] = sizeof(_c5), \
-		._s[5] = 5, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), _payload); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
+/* Previous OSes must go through older style...
+ *
+ * Format:
+ *      Items: [ ]
+ *      Item sizes: [
+ *          8 bits * count
+ *      ]
+ *      Item count: 8 bits
+ */
+
+#define OS_TRACE_CALL(_t, _p, _f, ...) __extension__({ \
+    if (os_trace_type_enabled(_t)) { \
+        _os_trace_verify_printf(_f, ##__VA_ARGS__); \
+        __attribute__((section("__TEXT,__oslogstring,cstring_literals"),internal_linkage)) static const char __f[] __asm(OS_STRINGIFY(OS_CONCAT(LOSTRACE_, __COUNTER__))) = _f; \
+        unsigned int __size = (unsigned int) __builtin_os_log_format_buffer_size(_f, ##__VA_ARGS__); \
+        uint8_t _buf[__size]; \
+        __builtin_os_log_format(_buf, _f, ##__VA_ARGS__); \
+        unsigned int tz = 0; \
+        uint8_t tb[__size]; \
+        uint8_t *buff = _buf; \
+        uint8_t *p = ++buff; \
+        uint8_t count = *p++; \
+        uint8_t trailer[count + 1]; \
+        trailer[count] = count; \
+        for (uint8_t ii = 0; ii < count; ii++) { \
+            uint8_t desc = *p++; \
+            uint8_t size = *p++; \
+            uint8_t *value = p; \
+            p += size; \
+            if ((desc >> 4) || (desc & 0x1)) { \
+                size = 0;\
+            }\
+            if (size) {\
+                memcpy(&tb[tz], value, size);\
+                tz += size;\
+            }\
+            trailer[ii] = size;\
+        }\
+        memcpy(&tb[tz], trailer, sizeof(trailer));\
+        tz += sizeof(trailer);\
+        _os_trace_with_buffer(&__dso_handle, __f, _t, tb, tz, _p);\
+    } \
 })
+#else
+#define OS_TRACE_CALL(...)
+#endif
 
-#define _os_trace_with_payload_7(_l, _m, _t, _1, _2, _3, _4, _5, _6, _payload) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	const __typeof__(_4) _c4 = _4; \
-	const __typeof__(_5) _c5 = _5; \
-	const __typeof__(_6) _c6 = _6; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3, _c4, _c5, _c6); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		__typeof__(_c4) _f4; \
-		__typeof__(_c5) _f5; \
-		__typeof__(_c6) _f6; \
-		unsigned char _s[7]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._f4 = _c4, ._s[3] = sizeof(_c4), \
-		._f5 = _c5, ._s[4] = sizeof(_c5), \
-		._f6 = _c6, ._s[5] = sizeof(_c6), \
-		._s[6] = 6, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), _payload); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
+// macros to re-order arguments so we can call log function
+#define _os_trace_with_payload_1(_t, _f, _p) OS_TRACE_CALL(_t, _p, _f)
+#define _os_trace_with_payload_2(_t, _f, _1, _p) OS_TRACE_CALL(_t, _p, _f, _1)
+#define _os_trace_with_payload_3(_t, _f, _1, _2, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2)
+#define _os_trace_with_payload_4(_t, _f, _1, _2, _3, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3)
+#define _os_trace_with_payload_5(_t, _f, _1, _2, _3, _4, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3, _4)
+#define _os_trace_with_payload_6(_t, _f, _1, _2, _3, _4, _5, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3, _4, _5)
+#define _os_trace_with_payload_7(_t, _f, _1, _2, _3, _4, _5, _6, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3, _4, _5, _6)
+#define _os_trace_with_payload_8(_t, _f, _1, _2, _3, _4, _5, _6, _7, _p) OS_TRACE_CALL(_t, _p, _f, _1, _2, _3, _4, _5, _6, _7)
 
-#define _os_trace_with_payload_8(_l, _m, _t, _1, _2, _3, _4, _5, _6, _7, _payload) __extension__({ \
-        _Pragma("clang diagnostic push") \
-        _Pragma("clang diagnostic ignored \"-Wpacked\"") \
-	const __typeof__(_1) _c1 = _1; \
-	const __typeof__(_2) _c2 = _2; \
-	const __typeof__(_3) _c3 = _3; \
-	const __typeof__(_4) _c4 = _4; \
-	const __typeof__(_5) _c5 = _5; \
-	const __typeof__(_6) _c6 = _6; \
-	const __typeof__(_7) _c7 = _7; \
-	_os_trace_verify_printf(_l, _c1, _c2, _c3, _c4, _c5, _c6, _c7); \
-	const struct __attribute__((packed)) { \
-		__typeof__(_c1) _f1; \
-		__typeof__(_c2) _f2; \
-		__typeof__(_c3) _f3; \
-		__typeof__(_c4) _f4; \
-		__typeof__(_c5) _f5; \
-		__typeof__(_c6) _f6; \
-		__typeof__(_c7) _f7; \
-		unsigned char _s[8]; \
-	} _buf = { \
-		._f1 = _c1, ._s[0] = sizeof(_c1), \
-		._f2 = _c2, ._s[1] = sizeof(_c2), \
-		._f3 = _c3, ._s[2] = sizeof(_c3), \
-		._f4 = _c4, ._s[3] = sizeof(_c4), \
-		._f5 = _c5, ._s[4] = sizeof(_c5), \
-		._f6 = _c6, ._s[5] = sizeof(_c6), \
-		._f7 = _c7, ._s[6] = sizeof(_c7), \
-		._s[7] = 7, \
-	}; \
-	_os_trace_with_buffer(&__dso_handle, _m, _t, &_buf, sizeof(_buf), _payload); \
-	__asm__(""); /* avoid tailcall */ \
-        _Pragma("clang diagnostic pop") \
-})
+#define _os_trace_call_n(_t, _f, ...) OS_TRACE_CALL(_t, NULL, _f, ##__VA_ARGS__)
 
 /*!
  *
@@ -466,7 +158,7 @@
 
 /*!
  * @define OS_TRACE_TYPE_RELEASE
- * Trace messages to be recorded on a typical user install.  These should be
+ * Trace messages to be captured on a typical user install.  These should be
  * limited to things which improve diagnosis of a failure/crash/hang. Trace
  * buffers are generally smaller on a production system.
  */
@@ -474,12 +166,19 @@
 
 /*!
  * @define OS_TRACE_TYPE_DEBUG
- * Trace messages to be recorded while debugger or other development tool is
+ * Trace messages to be captured while debugger or other development tool is
  * attached to the originator.
  */
 #define OS_TRACE_TYPE_DEBUG (1u << 1)
 
 /*!
+ * @define OS_TRACE_TYPE_INFO
+ * Trace messages that are captured when a debugger is attached, system or
+ * Application mode has been increased to include additional information.
+ */
+#define OS_TRACE_TYPE_INFO (1u << 2)
+
+/*!
  * @define OS_TRACE_TYPE_ERROR
  * Trace the message as an error and force a collection as a failure may be
  * imminent.
@@ -493,8 +192,6 @@
  */
 #define OS_TRACE_TYPE_FAULT ((1u << 7) | (1u << 6) | (1u << 0))
 
-__BEGIN_DECLS
-
 /*!
  * @typedef os_trace_payload_t
  * A block that populates an xpc_object_t of type XPC_TYPE_DICTIONARY to represent
@@ -512,7 +209,7 @@
  * @function os_trace
  *
  * @abstract
- * Insert a trace message into a buffer pool for later decoding.
+ * Always inserts a trace message into a buffer pool for later decoding.
  *
  * @discussion
  * Trace message that will be recorded on a typical user install. These should
@@ -525,25 +222,48 @@
  * to pass arbitrary strings will store a pointer that is unresolvable and
  * will generate an error during decode.
  *
- *		os_trace("network event: %ld, last seen: %ld, avg: %g", event_id, last_seen, avg);
+ *      os_trace("network event: %ld, last seen: %ld, avg: %g", event_id, last_seen, avg);
  */
-#define os_trace(format, ...) __extension__({                                                           \
-    _Pragma("clang diagnostic push")                                                                    \
-    _Pragma("clang diagnostic ignored \"-Wc++98-compat-pedantic\"")                                     \
-    _Static_assert(__builtin_constant_p(format), "format must be a constant string");                   \
-    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;                      \
-    OS_CONCAT(_os_trace, OS_COUNT_ARGS(__VA_ARGS__))(format, _m, OS_TRACE_TYPE_RELEASE, ##__VA_ARGS__); \
-    _Pragma("clang diagnostic pop")                                                                     \
-})
+#define os_trace(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_RELEASE, NULL, format, ##__VA_ARGS__)
+
+#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) &&  __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) \
+     || (defined(__WATCH_OS_VERSION_MIN_REQUIRED) &&  __WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0) \
+     || (defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) \
+     || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12)
+
+/*!
+ * @function os_trace_info
+ *
+ * @abstract
+ * Optionally inserts a trace message containing additional information into a
+ * buffer pool for later decoding.
+ *
+ * @discussion
+ * Trace messages that will be captured when additional information is needed
+ * and are not captured by default.  They will only be captured if the
+ * system/process/activity mode has been increased or if a Development tool has
+ * been attached to the process.
+ *
+ * @param format
+ * A printf-style format string that represents a human-readable message when
+ * the trace line is decoded.  Only scalar types are supported, attempts
+ * to pass arbitrary strings will store a pointer that is unresolvable and
+ * will generate an error during decode.
+ *
+ *      os_trace_info("network interface status %ld", status);
+ */
+#define os_trace_info(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_INFO, NULL, format, ##__VA_ARGS__)
+
+#endif
 
 /*!
  * @function os_trace_debug
  *
  * @abstract
- * Insert a trace message into a buffer pool for later decoding.
+ * Insert debug trace message into a buffer pool for later decoding.
  *
  * @discussion
- * Trace message to be recorded while debugger or other development tool is
+ * Debug trace message to be recorded while debugger or other development tool is
  * attached to the originator.  This is transported interprocess to help
  * diagnose the entire call chain including external helpers.
  *
@@ -553,13 +273,36 @@
  * to pass arbitrary strings will store a pointer that is unresolvable and
  * will generate an error during decode.
  *
- *		os_trace_debug("network interface status %ld", status);
+ *      os_trace_debug("network interface status %ld", status);
  */
-#define os_trace_debug(format, ...) __extension__({                                                     \
-    _Static_assert(__builtin_constant_p(format), "format must be a constant string");                   \
-    __attribute__((section("__TEXT,__os_trace_dbg"))) static const char _m[] = format;                  \
-    OS_CONCAT(_os_trace, OS_COUNT_ARGS(__VA_ARGS__))(format, _m, OS_TRACE_TYPE_DEBUG, ##__VA_ARGS__);   \
-})
+#define os_trace_debug(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_DEBUG, NULL, format, ##__VA_ARGS__)
+
+/*!
+ * @function os_trace_info_enabled
+ *
+ * @abstract
+ * Avoid unnecessary work for a trace point by checking if additional information
+ * is enabled.
+ *
+ * @discussion
+ * Avoid unnecessary work for a trace point by checking if additional information
+ * is enabled. Generally trace points should not involve expensive operations, but some
+ * circumstances warrant it.  Use this function to avoid doing the work unless
+ * debug level trace messages are requested.
+ *
+ *	if (os_trace_info_enabled()) {
+ *		os_trace_info("value = %d, average = %d",
+ *                            [[dict objectForKey: @"myKey"] intValue],
+ *			      (int) [self getAverage: dict]);
+ *	}
+ *
+ * @result
+ * Returns true if info types are enabled.
+ */
+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
+OS_EXPORT OS_NOTHROW OS_WARN_RESULT
+bool
+os_trace_info_enabled(void);
 
 /*!
  * @function os_trace_debug_enabled
@@ -582,12 +325,40 @@
  * @result
  * Returns true if debug mode is enabled.
  */
-__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0)
+__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(8.0))
 OS_EXPORT OS_NOTHROW OS_WARN_RESULT
 bool
 os_trace_debug_enabled(void);
 
 /*!
+ * @function os_trace_type_enabled
+ *
+ * @abstract
+ * Avoid unnecessary work for a trace point by checking a specific type
+ *
+ * @discussion
+ * Avoid unnecessary work for a trace point by checking a specific type
+ *
+ * @result
+ * Returns true if type is enabled.
+ */
+__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(8.0))
+OS_NOTHROW OS_WARN_RESULT OS_ALWAYS_INLINE
+static inline bool
+os_trace_type_enabled(uint8_t type)
+{
+    switch (type) {
+        case OS_TRACE_TYPE_INFO:
+            return os_trace_info_enabled();
+
+        case OS_TRACE_TYPE_DEBUG:
+            return os_trace_debug_enabled();
+    }
+
+    return true;
+}
+
+/*!
  * @function os_trace_error
  *
  * @abstract
@@ -604,13 +375,9 @@
  * to pass arbitrary strings will store a pointer that is unresolvable and
  * will generate an error during decode.
  *
- *		os_trace_error("socket %d connection timeout %ld", fd, secs);
+ *      os_trace_error("socket %d connection timeout %ld", fd, secs);
  */
-#define os_trace_error(format, ...) __extension__({                                                     \
-    _Static_assert(__builtin_constant_p(format), "format must be a constant string");                   \
-    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;                      \
-    OS_CONCAT(_os_trace, OS_COUNT_ARGS(__VA_ARGS__))(format, _m, OS_TRACE_TYPE_ERROR, ##__VA_ARGS__);   \
-})
+#define os_trace_error(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_ERROR, NULL, format, ##__VA_ARGS__)
 
 /*!
  * @function os_trace_fault
@@ -629,13 +396,9 @@
  * to pass arbitrary strings will store a pointer that is unresolvable and
  * will generate an error during decode.
  *
- *		os_trace_fault("failed to lookup uid %d - aborting", uid);
+ *      os_trace_fault("failed to lookup uid %d - aborting", uid);
  */
-#define os_trace_fault(format, ...) __extension__({                                                     \
-    _Static_assert(__builtin_constant_p(format), "format must be a constant string");                   \
-    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;                      \
-    OS_CONCAT(_os_trace, OS_COUNT_ARGS(__VA_ARGS__))(format, _m, OS_TRACE_TYPE_FAULT, ##__VA_ARGS__);   \
-})
+#define os_trace_fault(format, ...) OS_TRACE_CALL(OS_TRACE_TYPE_FAULT, NULL, format, ##__VA_ARGS__)
 
 #if __has_include(<xpc/xpc.h>)
 /*!
@@ -661,33 +424,43 @@
  *
  *   os_trace_with_payload("network event %ld", event, ^(xpc_object_t xdict) {
  *
- *		// validate the network interface and address where what was expected
- *		xpc_dictionary_set_string(xdict, "network", ifp->ifa_name);
- *		xpc_dictionary_set_string(xdict, "ip_address", _get_address(ifp));
+ *      // validate the network interface and address where what was expected
+ *      xpc_dictionary_set_string(xdict, "network", ifp->ifa_name);
+ *      xpc_dictionary_set_string(xdict, "ip_address", _get_address(ifp));
  *   });
  */
-#define os_trace_with_payload(format, ...) __extension__({                                                              \
-    _Static_assert(__builtin_constant_p(format), "format must be a constant string");                                   \
-    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;                                      \
-    OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))(format, _m, OS_TRACE_TYPE_RELEASE, ##__VA_ARGS__);    \
+#define os_trace_with_payload(format, ...) __extension__({ \
+    OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))(OS_TRACE_TYPE_RELEASE, format, ##__VA_ARGS__); \
+})
+
+#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) &&  __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) \
+    || (defined(__WATCH_OS_VERSION_MIN_REQUIRED) &&  __WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0) \
+    || (defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) \
+    || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12)
+
+#define os_trace_info_with_payload(format, ...) __extension__({ \
+    OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))(OS_TRACE_TYPE_INFO, format, ##__VA_ARGS__); \
 })
 
-#define os_trace_debug_with_payload(format, ...) __extension__({                                                    \
-    _Static_assert(__builtin_constant_p(format), "format must be a constant string");                               \
-    __attribute__((section("__TEXT,__os_trace_dbg"))) static const char _m[] = format;                              \
-    OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))(format, _m, OS_TRACE_TYPE_DEBUG, ##__VA_ARGS__);  \
+#else
+
+__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
+OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED
+void
+os_trace_info_with_payload(const char *format, ...);
+
+#endif
+
+#define os_trace_debug_with_payload(format, ...) __extension__({ \
+    OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))(OS_TRACE_TYPE_DEBUG, format, ##__VA_ARGS__); \
 })
 
-#define os_trace_error_with_payload(format, ...) __extension__({                                                    \
-    _Static_assert(__builtin_constant_p(format), "format must be a constant string");                               \
-    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;                                  \
-    OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))(format, _m, OS_TRACE_TYPE_ERROR, ##__VA_ARGS__);  \
+#define os_trace_error_with_payload(format, ...) __extension__({ \
+    OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))(OS_TRACE_TYPE_ERROR, format, ##__VA_ARGS__); \
 })
 
-#define os_trace_fault_with_payload(format, ...) __extension__({                                                    \
-    _Static_assert(__builtin_constant_p(format), "format must be a constant string");                               \
-    __attribute__((section("__TEXT,__os_trace"))) static const char _m[] = format;                                  \
-    OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))(format, _m, OS_TRACE_TYPE_FAULT, ##__VA_ARGS__);  \
+#define os_trace_fault_with_payload(format, ...) __extension__({ \
+    OS_CONCAT(_os_trace_with_payload, OS_COUNT_ARGS(__VA_ARGS__))(OS_TRACE_TYPE_FAULT, format, ##__VA_ARGS__); \
 })
 
 #endif // __has_include(<xpc/xpc.h>)
@@ -698,8 +471,8 @@
  * @abstract
  * Internal function to support pre-encoded buffer.
  */
-__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0)
-OS_EXPORT OS_NOTHROW
+__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(8.0))
+OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED
 void
 _os_trace_with_buffer(void *dso, const char *message, uint8_t type, const void *buffer, size_t buffer_size, os_trace_payload_t payload);
 
