#endif
#if __has_attribute(always_inline)
-#define OSATOMIC_INLINE static __inline
-#else
#define OSATOMIC_INLINE static __inline __attribute__((__always_inline__))
+#else
+#define OSATOMIC_INLINE static __inline
#endif
OSATOMIC_INLINE
#define OS_OVERLOADABLE
#endif
-#if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
+#if __has_attribute(enum_extensibility)
+#define __OS_ENUM_ATTR __attribute__((enum_extensibility(open)))
+#define __OS_ENUM_ATTR_CLOSED __attribute__((enum_extensibility(closed)))
+#else
+#define __OS_ENUM_ATTR
+#define __OS_ENUM_ATTR_CLOSED
+#endif // __has_attribute(enum_extensibility)
+
+#if __has_attribute(flag_enum)
+/*!
+ * Compile with -Wflag-enum and -Wassign-enum to enforce at definition and
+ * assignment, respectively, i.e. -Wflag-enum prevents you from creating new
+ * enumeration values from illegal values within the enum definition, and
+ * -Wassign-enum prevents you from assigning illegal values to a variable of the
+ * enum type.
+ */
+#define __OS_OPTIONS_ATTR __attribute__((flag_enum))
+#else
+#define __OS_OPTIONS_ATTR
+#endif // __has_attribute(flag_enum)
+
+#if __has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum) || \
+ __has_extension(cxx_strong_enums)
#define OS_ENUM(_name, _type, ...) \
typedef enum : _type { __VA_ARGS__ } _name##_t
+#define OS_CLOSED_ENUM(_name, _type, ...) \
+ typedef enum : _type { __VA_ARGS__ } \
+ __OS_ENUM_ATTR_CLOSED _name##_t
+#define OS_OPTIONS(_name, _type, ...) \
+ typedef enum : _type { __VA_ARGS__ } \
+ __OS_ENUM_ATTR __OS_OPTIONS_ATTR _name##_t
+#define OS_CLOSED_OPTIONS(_name, _type, ...) \
+ typedef enum : _type { __VA_ARGS__ } \
+ __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR _name##_t
#else
+/*!
+ * There is unfortunately no good way in plain C to have both fixed-type enums
+ * and enforcement for clang's enum_extensibility extensions. The primary goal
+ * of these macros is to allow you to define an enum and specify its width in a
+ * single statement, and for plain C that is accomplished by defining an
+ * anonymous enum and then separately typedef'ing the requested type name to the
+ * requested underlying integer type. So the type emitted actually has no
+ * relationship at all to the enum, and therefore while the compiler could
+ * enforce enum extensibility if you used the enum type, it cannot do so if you
+ * use the "_t" type resulting from this expression.
+ *
+ * But we still define a named enum type and decorate it appropriately for you,
+ * so if you really want the enum extensibility enforcement, you can use the
+ * enum type yourself, i.e. when compiling with a C compiler:
+ *
+ * OS_CLOSED_ENUM(my_type, uint64_t,
+ * FOO,
+ * BAR,
+ * BAZ,
+ * );
+ *
+ * my_type_t mt = 98; // legal
+ * enum my_type emt = 98; // illegal
+ *
+ * But be aware that the underlying enum type's width is subject only to the C
+ * language's guarantees -- namely that it will be compatible with int, char,
+ * and unsigned char. It is not safe to rely on the size of this type.
+ *
+ * When compiling in ObjC or C++, both of the above assignments are illegal.
+ */
+#define __OS_ENUM_C_FALLBACK(_name, _type, ...) \
+ typedef _type _name##_t; enum _name { __VA_ARGS__ }
+
#define OS_ENUM(_name, _type, ...) \
- enum { __VA_ARGS__ }; typedef _type _name##_t
-#endif
+ typedef _type _name##_t; enum { __VA_ARGS__ }
+#define OS_CLOSED_ENUM(_name, _type, ...) \
+ __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \
+ __OS_ENUM_ATTR_CLOSED
+#define OS_OPTIONS(_name, _type, ...) \
+ __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \
+ __OS_ENUM_ATTR __OS_OPTIONS_ATTR
+#define OS_CLOSED_OPTIONS(_name, _type, ...) \
+ __OS_ENUM_C_FALLBACK(_name, _type, ## __VA_ARGS__) \
+ __OS_ENUM_ATTR_CLOSED __OS_OPTIONS_ATTR
+#endif // __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
#if __has_feature(attribute_availability_swift)
// equivalent to __SWIFT_UNAVAILABLE from Availability.h
__BEGIN_DECLS
#define OS_UNFAIR_LOCK_AVAILABILITY \
- __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) \
- __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
+ __API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
/*!
* @typedef os_unfair_lock
* defined, they contain thread ownership information that the system may use
* to attempt to resolve priority inversions.
*
- * This lock must be unlocked from the same thread that locked it, attemps to
+ * This lock must be unlocked from the same thread that locked it, attempts to
* unlock from a different thread will cause an assertion aborting the process.
*
* This lock must not be accessed from multiple processes or threads via shared
#define os_atomic_rmw_loop_give_up(expr) \
os_atomic_rmw_loop_give_up_with_fence(relaxed, expr)
-#define os_atomic_tsx_xacq_cmpxchgv(p, e, v, g) \
- os_atomic_cmpxchgv((p), (e), (v), (g), acquire)
-#define os_atomic_tsx_xrel_store(p, v) \
- os_atomic_store(p, v, release)
-#define os_atomic_tsx_xacq_cmpxchgv2o(p, f, e, v, g) \
- os_atomic_tsx_xacq_cmpxchgv(&(p)->f, (e), (v), (g))
-#define os_atomic_tsx_xrel_store2o(p, f, v) \
- os_atomic_tsx_xrel_store(&(p)->f, (v))
-
-#if defined(__x86_64__) || defined(__i386__)
-#pragma mark -
-#pragma mark x86
-
-
-#endif
-
#endif // __OS_EXPOSE_INTERNALS_INDIRECT__
OS_LOCK_TYPE_STRUCT(type) * osl_type OS_UNUSED; \
uintptr_t _osl_##type##_opaque[size-1] OS_UNUSED; \
public: \
- constexpr OS_LOCK(type)() : \
+ constexpr OS_LOCK(type)() : \
osl_type(&OS_LOCK_TYPE_REF(type)), _osl_##type##_opaque() {} \
} OS_LOCK(type)
#define OS_LOCK_INIT(type) {}
OS_LOCK_T_MEMBER(nospin);
OS_LOCK_T_MEMBER(spin);
OS_LOCK_T_MEMBER(handoff);
- OS_LOCK_T_MEMBER(eliding);
- OS_LOCK_T_MEMBER(transactional);
} os_lock_t;
#endif
#define OS_LOCK_HANDOFF_INIT OS_LOCK_INIT(handoff)
-#if !TARGET_OS_IPHONE
-/*!
- * @typedef os_lock_eliding_s
- *
- * @abstract
- * os_lock variant that uses hardware lock elision support if available to allow
- * multiple processors to concurrently execute a critical section as long as
- * they don't perform conflicting operations on each other's data. In case of
- * conflict, the lock reverts to exclusive operation and os_lock_spin_s behavior
- * on contention (at potential extra cost for the aborted attempt at lock-elided
- * concurrent execution). If hardware HLE support is not present, this lock
- * variant behaves like os_lock_spin_s.
- *
- * @discussion
- * IMPORTANT: Use of this lock variant MUST be extensively tested on hardware
- * with HLE support to ensure the data access pattern and length of the critical
- * section allows lock-elided execution to succeed frequently enough to offset
- * the cost of any aborted concurrent execution.
- *
- * Must be initialized with OS_LOCK_ELIDING_INIT
- */
-__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_NA)
-OS_EXPORT OS_LOCK_TYPE_DECL(eliding);
-OS_LOCK_DECL(eliding, 8) OS_ALIGNED(64);
-#define OS_LOCK_ELIDING_INIT OS_LOCK_INIT(eliding)
-
-/*!
- * @typedef os_lock_transactional_s
- *
- * @abstract
- * os_lock variant that uses hardware restricted transactional memory support if
- * available to allow multiple processors to concurrently execute the critical
- * section as a transactional region. If transactional execution aborts, the
- * lock reverts to exclusive operation and os_lock_spin_s behavior on contention
- * (at potential extra cost for the aborted attempt at transactional concurrent
- * execution). If hardware RTM support is not present, this lock variant behaves
- * like os_lock_eliding_s.
- *
- * @discussion
- * IMPORTANT: Use of this lock variant MUST be extensively tested on hardware
- * with RTM support to ensure the data access pattern and length of the critical
- * section allows transactional execution to succeed frequently enough to offset
- * the cost of any aborted transactions.
- *
- * Must be initialized with OS_LOCK_TRANSACTIONAL_INIT
- */
-__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_NA)
-OS_EXPORT OS_LOCK_TYPE_DECL(transactional);
-OS_LOCK_DECL(transactional, 8) OS_ALIGNED(64);
-#define OS_LOCK_TRANSACTIONAL_INIT OS_LOCK_INIT(transactional)
-#endif
-
__BEGIN_DECLS
/*!
* contains thread ownership information that the system may use to attempt to
* resolve priority inversions.
*
- * This lock must be unlocked from the same thread that locked it, attemps to
+ * This lock must be unlocked from the same thread that locked it, attempts to
* unlock from a different thread will cause an assertion aborting the process.
*
* This lock must not be accessed from multiple processes or threads via shared
* When this flag is used, the code running under the critical section should
* be well known and under your control (Generally it should not call into
* framework code).
+ *
+ * @const OS_UNFAIR_LOCK_ADAPTIVE_SPIN
+ * This flag allows for the kernel to use adaptive spinning when the holder
+ * of the lock is currently on core. This should only be used for locks
+ * where the protected critical section is always extremely short.
*/
-OS_ENUM(os_unfair_lock_options, uint32_t,
- OS_UNFAIR_LOCK_NONE
+OS_OPTIONS(os_unfair_lock_options, uint32_t,
+ OS_UNFAIR_LOCK_NONE OS_SWIFT_NAME(None)
OS_UNFAIR_LOCK_AVAILABILITY = 0x00000000,
- OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION
+ OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION OS_SWIFT_NAME(DataSynchronization)
OS_UNFAIR_LOCK_AVAILABILITY = 0x00010000,
+ OS_UNFAIR_LOCK_ADAPTIVE_SPIN OS_SWIFT_NAME(AdaptiveSpin)
+ __API_AVAILABLE(macos(10.15), ios(13.0),
+ tvos(13.0), watchos(6.0), bridgeos(4.0)) = 0x00040000,
);
+#if __swift__
+#define OS_UNFAIR_LOCK_OPTIONS_COMPAT_FOR_SWIFT(name) \
+ static const os_unfair_lock_options_t \
+ name##_FOR_SWIFT OS_SWIFT_NAME(name) = name
+OS_UNFAIR_LOCK_OPTIONS_COMPAT_FOR_SWIFT(OS_UNFAIR_LOCK_NONE);
+OS_UNFAIR_LOCK_OPTIONS_COMPAT_FOR_SWIFT(OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION);
+OS_UNFAIR_LOCK_OPTIONS_COMPAT_FOR_SWIFT(OS_UNFAIR_LOCK_ADAPTIVE_SPIN);
+#undef OS_UNFAIR_LOCK_OPTIONS_COMPAT_FOR_SWIFT
+#endif
+
/*!
* @function os_unfair_lock_lock_with_options
*
os_unfair_lock_assert_not_owner(&lock->ourl_lock);
}
+/*!
+ * @function os_unfair_recursive_lock_owned
+ *
+ * @abstract
+ * This function is reserved for the use of people who want to soft-fault
+ * when locking models have been violated.
+ *
+ * @discussion
+ * This is meant for SQLite use to detect existing misuse of the API surface,
+ * and is not meant for anything else than calling os_log_fault() when such
+ * contracts are violated.
+ *
+ * There's little point to use this value for logic as the
+ * os_unfair_recursive_lock is already recursive anyway.
+ */
+__OSX_AVAILABLE(10.15) __IOS_AVAILABLE(13.0)
+__TVOS_AVAILABLE(13.0) __WATCHOS_AVAILABLE(6.0)
+OS_EXPORT OS_NOTHROW OS_NONNULL_ALL
+bool
+os_unfair_recursive_lock_owned(os_unfair_recursive_lock_t lock);
+
+/*!
+ * @function os_unfair_recursive_lock_unlock_forked_child
+ *
+ * @abstract
+ * Function to be used in an atfork child handler to unlock a recursive unfair
+ * lock.
+ *
+ * @discussion
+ * This function helps with handling recursive locks in the presence of fork.
+ *
+ * It is typical to setup atfork handlers that will:
+ * - take the lock in the pre-fork handler,
+ * - drop the lock in the parent handler,
+ * - reset the lock in the forked child.
+ *
+ * However, because a recursive lock may have been held by the current thread
+ * already, reseting needs to act like an unlock. This function serves for this
+ * purpose. Unlike os_unfair_recursive_lock_unlock(), this function will fixup
+ * the lock ownership to match the new identity of the thread after fork().
+ */
+__OSX_AVAILABLE(10.15) __IOS_AVAILABLE(13.0)
+__TVOS_AVAILABLE(13.0) __WATCHOS_AVAILABLE(6.0)
+OS_EXPORT OS_NOTHROW OS_NONNULL_ALL
+void
+os_unfair_recursive_lock_unlock_forked_child(os_unfair_recursive_lock_t lock);
+
#if __has_attribute(cleanup)
/*!
*/
#include <mach/arm/syscall_sw.h>
+#include <mach/arm64/asm.h>
+#include <machine/cpu_capabilities.h>
#define MMU_I_CLINE 6 // cache line size as 1<<MMU_I_CLINE (64)
_sys_icache_invalidate:
// see InvalidatePoU_IcacheRegion() in xnu/osfmk/arm64/caches_asm.s
cbz x1, 2f // length > 0 ?
- and x8, x0, #~((1<<MMU_I_CLINE)-1) // cacheline align address
- and x9, x0, #((1<<MMU_I_CLINE)-1) // extend length by alignment
- add x9, x1, x9
- sub x9, x9, #1
- mov x10, #-1
- eor x9, x10, x9, lsr #MMU_I_CLINE // compute cacheline counter
+ MOV64 x8, _COMM_PAGE_CPU_CAPABILITIES
+ ldr w8, [x8]
+ and x9, x0, #~((1<<MMU_I_CLINE)-1) // cacheline align address
+ and x10, x0, #((1<<MMU_I_CLINE)-1) // extend length by alignment
+ add x10, x1, x10
+ sub x10, x10, #1
+ mov x11, #-1
+ eor x10, x11, x10, lsr #MMU_I_CLINE // compute cacheline counter
+ dsb ish
1:
- ic ivau, x8 // invalidate icache line
- add x8, x8, #1<<MMU_I_CLINE // next cacheline address
- add x9, x9, #1 // decrement cacheline counter
- cbnz x9, 1b
+ ic ivau, x9 // invalidate icache line
+ add x9, x9, #1<<MMU_I_CLINE // next cacheline address
+ adds x10, x10, #1 // decrement cacheline counter
+ b.ne 1b
dsb ish
+ tbnz w8, kHasICDSBShift, 2f
isb
2:
ret
ret
#if 0
-// Above generated by clang from:
+// Above based on output generated by clang from:
static void __attribute((used))
sys_icache_invalidate(uintptr_t start, size_t length)
{
if (!length) return;
+ boolean_t hasICDSB = (*(uint32_t*)(uintptr_t)_COMM_PAGE_CPU_CAPABILITIES) & kHasICDSB;
uintptr_t addr = start & ~((1 << MMU_I_CLINE) - 1);
length += start & ((1 << MMU_I_CLINE) - 1);
size_t count = ((length - 1) >> MMU_I_CLINE) + 1;
+ asm volatile("dsb ish" ::: "memory");
while (count--) {
asm("ic ivau, %[addr]" :: [addr] "r" (addr) : "memory");
addr += (1 << MMU_I_CLINE);
}
- asm volatile("dsb ish\n\tisb" ::: "memory");
+ if (hasICDSB) {
+ asm volatile("dsb ish" ::: "memory");
+ } else {
+ asm volatile("dsb ish" ::: "memory");
+ asm volatile("isb" ::: "memory");
+ }
}
+
+cbz x1, 0x44
+mov x8, #0xfffff0000
+movk x8, #0xc020
+ldr w8, [x8]
+and x9, x0, #0xffffffffffffffc0
+and x10, x0, #0x3f
+add x10, x1, x10
+sub x10, x10, #0x1
+mov x11, #-0x1
+eor x10, x11, x10, lsr #6
+ic ivau, x9
+add x9, x9, #0x40
+adds x10, x10, #0x1
+b.ne 0x28
+dsb ish
+tbnz w8, #0x2, 0x44
+isb
+ret
+
#endif
#if !TARGET_OS_SIMULATOR
__pfz_setup(apple);
#endif
+#if !TARGET_OS_DRIVERKIT
_simple_asl_init(envp, vars);
+#endif
#if !VARIANT_STATIC
__libkernel_platform_init(&_platform_string_functions);
_Static_assert(OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION ==
ULF_WAIT_WORKQ_DATA_CONTENTION,
- "check value for OS_UNFAIR_LOCK_OPTIONS_MASK");
+ "check value for OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION");
+_Static_assert(OS_UNFAIR_LOCK_ADAPTIVE_SPIN ==
+ ULF_WAIT_ADAPTIVE_SPIN,
+ "check value for OS_UNFAIR_LOCK_ADAPTIVE_SPIN");
#define OS_UNFAIR_LOCK_OPTIONS_MASK \
- (os_unfair_lock_options_t)(OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION)
+ (os_unfair_lock_options_t)(OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION | \
+ OS_UNFAIR_LOCK_ADAPTIVE_SPIN)
#define OS_UNFAIR_LOCK_ALLOW_ANONYMOUS_OWNER 0x01000000u
OS_ATOMIC_EXPORT
bool os_unfair_recursive_lock_tryunlock4objc(os_unfair_recursive_lock_t lock);
+OS_ATOMIC_EXPORT
+void os_unfair_recursive_lock_unlock_forked_child(os_unfair_recursive_lock_t lock);
+
static inline os_lock_owner_t
_os_unfair_lock_owner(os_unfair_lock_t lock)
return OS_ULOCK_OWNER(os_atomic_load(&l->oul_value, relaxed));
}
+
+bool
+os_unfair_recursive_lock_owned(os_unfair_recursive_lock_t lock)
+{
+ return _os_unfair_lock_owner(&lock->ourl_lock) ==
+ _os_lock_owner_get_self();
+}
+
+
void
os_unfair_recursive_lock_lock_with_options(os_unfair_recursive_lock_t lock,
os_unfair_lock_options_t options)
return false;
}
+void
+os_unfair_recursive_lock_unlock_forked_child(os_unfair_recursive_lock_t lock)
+{
+ _os_unfair_lock_t l = (_os_unfair_lock_t)&lock->ourl_lock;
+
+ if (os_atomic_load(&l->oul_value, relaxed) == OS_LOCK_NO_OWNER) {
+ __LIBPLATFORM_CLIENT_CRASH__(0, "Lock was not held");
+ }
+ if (lock->ourl_count) {
+ os_lock_owner_t self = _os_lock_owner_get_self();
+ lock->ourl_count--;
+ os_atomic_store(&l->oul_value, self, relaxed);
+ } else {
+ os_atomic_store(&l->oul_value, OS_LOCK_NO_OWNER, relaxed);
+ }
+}
+
#pragma mark -
#pragma mark _os_lock_unfair_t
return _os_once_gate_wait(og, ctxt, func, self);
}
-
-#pragma mark -
-#pragma mark os_lock_eliding_t
-
-#if !TARGET_OS_IPHONE
-
-#define _os_lock_eliding_t _os_lock_spin_t
-#define _os_lock_eliding_lock _os_lock_spin_lock
-#define _os_lock_eliding_trylock _os_lock_spin_trylock
-#define _os_lock_eliding_unlock _os_lock_spin_unlock
-OS_LOCK_METHODS_DECL(eliding);
-OS_LOCK_TYPE_INSTANCE(eliding);
-
-#pragma mark -
-#pragma mark os_lock_transactional_t
-
-OS_LOCK_STRUCT_DECL_INTERNAL(transactional,
- uintptr_t volatile osl_lock;
-);
-
-#define _os_lock_transactional_t _os_lock_eliding_t
-#define _os_lock_transactional_lock _os_lock_eliding_lock
-#define _os_lock_transactional_trylock _os_lock_eliding_trylock
-#define _os_lock_transactional_unlock _os_lock_eliding_unlock
-OS_LOCK_METHODS_DECL(transactional);
-OS_LOCK_TYPE_INSTANCE(transactional);
-
-#endif // !TARGET_OS_IPHONE
#include <platform/string.h>
#include <platform/compat.h>
+#if TARGET_OS_DRIVERKIT
+// DriverKit processes log directly to kernel log
+#include <sys/log_data.h>
+OS_ENUM(os_log_type, uint8_t,
+ OS_LOG_TYPE_DEFAULT = 0x00,
+ OS_LOG_TYPE_INFO = 0x01,
+ OS_LOG_TYPE_DEBUG = 0x02,
+);
+#else // !TARGET_OS_DRIVERKIT
+
#define ASL_LOG_PATH _PATH_LOG
extern ssize_t __sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t);
* requires knowledge of the format used by ASL.
*/
-static const char *
-_simple_asl_escape_key(unsigned char c)
-{
- switch(c)
- {
- case '\\': return "\\\\";
- case '[': return "\\[";
- case ']': return "\\]";
- case '\n': return "\\n";
- case ' ': return "\\s";
- }
-
- return NULL;
-}
-
-static const char *
-_simple_asl_escape_val(unsigned char c)
-{
- switch(c)
- {
- case '\\': return "\\\\";
- case '[': return "\\[";
- case ']': return "\\]";
- case '\n': return "\\n";
- }
-
- return NULL;
-}
-
__attribute__((visibility("hidden")))
void
_simple_asl_init(const char *envp[], const struct ProgramVars *vars)
_simple_asl_connect(const char *log_path)
{
int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
- if (fd == -1) return;
+ if (fd == -1) return -1;
fcntl(fd, F_SETFD, FD_CLOEXEC);
return ctx->asl_fd;
#endif
}
+#endif // !TARGET_OS_DRIVERKIT
+
+static const char *
+_simple_asl_escape_key(unsigned char c)
+{
+ switch(c)
+ {
+ case '\\': return "\\\\";
+ case '[': return "\\[";
+ case ']': return "\\]";
+ case '\n': return "\\n";
+ case ' ': return "\\s";
+ }
+
+ return NULL;
+}
+
+static const char *
+_simple_asl_escape_val(unsigned char c)
+{
+ switch(c)
+ {
+ case '\\': return "\\\\";
+ case '[': return "\\[";
+ case ']': return "\\]";
+ case '\n': return "\\n";
+ }
+
+ return NULL;
+}
_SIMPLE_STRING
_simple_asl_msg_new(void)
void
_simple_asl_send(_SIMPLE_STRING __b)
{
+#if !TARGET_OS_DRIVERKIT
struct timeval tv;
int asl_fd = _simple_asl_get_fd();
if (asl_fd < 0) return;
cp = _simple_string(__b);
__sendto(asl_fd, cp, strlen(cp), 0, NULL, 0);
} while (0);
+#else // TARGET_OS_DRIVERKIT
+ char *cp;
+ cp = _simple_string(__b);
+ log_data_as_kernel(0, OS_LOG_TYPE_DEFAULT, cp, strlen(cp) + 1);
+#endif // TARGET_OS_DRIVERKIT
}
void
_simple_asl_log_prog(int level, const char *facility, const char *message, const char *prog)
{
- char lstr[2];
-
_SIMPLE_STRING b = _simple_asl_msg_new();
if (b == NULL) return;
+#if !TARGET_OS_DRIVERKIT
+ char lstr[2];
if (level < 0) level = 0;
if (level > 7) level = 7;
lstr[0] = level + '0';
_simple_asl_msg_set(b, "Facility", facility);
_simple_asl_msg_set(b, "Message", message);
_simple_asl_send(b);
+#else // TARGET_OS_DRIVERKIT
+ if (prog) _simple_asl_msg_set(b, "Sender", prog);
+ _simple_asl_msg_set(b, "Facility", facility);
+ _simple_asl_msg_set(b, "Message", message);
+
+ os_log_type_t type = level > ASL_LEVEL_INFO ? OS_LOG_TYPE_DEFAULT :
+ (level > ASL_LEVEL_DEBUG ? OS_LOG_TYPE_INFO : OS_LOG_TYPE_DEBUG);
+
+ char *cp;
+ cp = _simple_string(b);
+ log_data_as_kernel(0, type, cp, strlen(cp) + 1);
+#endif // TARGET_OS_DRIVERKIT
_simple_sfree(b);
}
void
_simple_asl_log(int level, const char *facility, const char *message)
{
+#if !TARGET_OS_DRIVERKIT
_simple_asl_log_prog(level, facility, message,
_simple_asl_get_context()->progname);
+#else // TARGET_OS_DRIVERKIT
+ _simple_asl_log_prog(level, facility, message, NULL);
+#endif // TARGET_OS_DRIVERKIT
}
+#if !TARGET_OS_DRIVERKIT
static struct asl_context *
_simple_asl_get_context(void)
{
ctx->progname = "unknown";
ctx->asl_fd = -1;
}
+#endif // !TARGET_OS_DRIVERKIT
put_s(b, esc, cp);
}
+/*
+ * Output the octal string representing the number in "n". "width" is
+ * the minimum field width, and "zero" is a boolean value, true for zero padding
+ * (otherwise blank padding).
+ */
+static void
+oct(BUF *b, _esc_func esc, unsigned long long n, int width, int zero)
+{
+ char buf[32];
+ char *cp = buf + sizeof(buf);
+ ssize_t pad;
+
+ *--cp = 0;
+ if (n) {
+ while (n) {
+ *--cp = (n % 8) + '0';
+ n /= 8;
+ }
+ } else {
+ *--cp = '0';
+ }
+ pad = width - strlen(cp);
+ zero = zero ? '0' : ' ';
+ while (pad-- > 0) {
+ put_c(b, esc, zero);
+ }
+ put_s(b, esc, cp);
+}
+
/*
* Output the hex string representing the number in "n". "width" is the
* minimum field width, and "zero" is a boolean value, true for zero padding
lflag++;
fmt++;
continue;
+ case 'o':
+ switch (lflag) {
+ case 0:
+ oct(b, esc, va_arg(ap, int), width, zero);
+ break;
+ case 1:
+ oct(b, esc, va_arg(ap, long), width, zero);
+ break;
+ default:
+ oct(b, esc, va_arg(ap, long long), width, zero);
+ break;
+ }
+ break;
case 'p':
hex(b, esc, (unsigned long)va_arg(ap, void *), width, zero, 0, 1);
break;
#include <platform/string.h>
+#if !VARIANT_STATIC
+// to satisfy compiler-generated memset inside libplatform (e.g. makecontext)
+__attribute__((visibility("hidden")))
+void *
+memset(void *b, int c, size_t len)
+{
+ return _platform_memset(b, c, len);
+}
+#endif
+
#if !_PLATFORM_OPTIMIZED_MEMSET
void *
OSATOMIC_PREPROCESSOR_DEFINITIONS = OSATOMIC_USE_INLINED=0 OSATOMIC_DEPRECATED=0
-PUBLIC_HEADERS_FOLDER_PATH = /usr/include/libkern
-PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/libkern
+PUBLIC_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/include/libkern
+PRIVATE_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/local/include/libkern
__platform_bzero ___bzero
+__os_lock_type_spin __os_lock_type_eliding
+__os_lock_type_spin __os_lock_type_transactional
_os_unfair_lock_lock_with_options _os_unfair_lock_lock_with_options_4Libc
_os_unfair_lock_unlock _os_unfair_lock_unlock_4Libc
BUILD_VARIANTS = normal debug dyld static
EXECUTABLE_PREFIX = lib
-INSTALL_PATH = /usr/lib/system
-PUBLIC_HEADERS_FOLDER_PATH = /usr/include
-PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include
+
+// Pick the right install locations depending on whether building for DriverKit SDK or not
+SDK_INSTALL_VARIANT = $(SDK_INSTALL_VARIANT_$(DRIVERKIT))
+SDK_INSTALL_VARIANT_1 = driverkit
+SDK_INSTALL_VARIANT_ = default
+SDK_INSTALL_ROOT = $(SDK_INSTALL_ROOT_$(SDK_INSTALL_VARIANT))
+SDK_INSTALL_ROOT_driverkit = $(DRIVERKITROOT)
+SDK_INSTALL_HEADERS_ROOT = $(SDK_INSTALL_HEADERS_ROOT_$(SDK_INSTALL_VARIANT))
+SDK_INSTALL_HEADERS_ROOT_driverkit = $(SDK_INSTALL_ROOT)/$(SDK_RUNTIME_HEADERS_PREFIX)
+SDK_RUNTIME_HEADERS_PREFIX = Runtime
+
+INSTALL_PATH = $(SDK_INSTALL_ROOT)/usr/lib/system
+PUBLIC_HEADERS_FOLDER_PATH=$(SDK_INSTALL_HEADERS_ROOT)/usr/include
+PRIVATE_HEADERS_FOLDER_PATH=$(SDK_INSTALL_HEADERS_ROOT)/usr/local/include
USE_HEADERMAP = NO
SKIP_INSTALL = YES
GCC_OPTIMIZATION_LEVEL = s
// TODO: Remove -fno-stack-protector once it has been moved down (after libproc is moved down)
-OTHER_CFLAGS = -fno-stack-protector -fdollars-in-identifiers -fno-common -fverbose-asm $(COMPILER_CFLAGS) $(PLATFORM_CFLAGS) -isystem $(SYSTEM_FRAMEWORK_HEADERS)
+OTHER_CFLAGS = -fno-stack-protector -fdollars-in-identifiers -fno-common -fverbose-asm $(COMPILER_CFLAGS) $(PLATFORM_CFLAGS)
OTHER_CFLAGS_normal = -momit-leaf-frame-pointer
OTHER_CFLAGS_debug = -fno-inline -O0
STRIP_INSTALLED_PRODUCT_debug = YES
SRCROOT_SEARCH_PATHS = $(SRCROOT)/private $(SRCROOT)/include $(SRCROOT)/internal
-SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
-HEADER_SEARCH_PATHS = $(SRCROOT_SEARCH_PATHS) $(SDKROOT)/usr/local/include $(SDKROOT)/usr/include $(inherited)
+HEADER_SEARCH_PATHS = $(SRCROOT_SEARCH_PATHS) $(inherited)
+SYSTEM_HEADER_SEARCH_PATHS = $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/System/Library/Frameworks/System.framework/PrivateHeaders $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/usr/local/include $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/usr/include
+SYSTEM_FRAMEWORK_SEARCH_PATHS = $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/System/Library/Frameworks
DEAD_CODE_STRIPPING = NO
STRING_LIBRARIES = $(CONFIGURATION_BUILD_DIR)/libstring_i386_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libstring_x86_64_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libstring_arm_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libstring_arm64_$(CURRENT_VARIANT).a $(EXTRA_STRING_LIBRARIES)
UCONTEXT_LIBRARIES = $(CONFIGURATION_BUILD_DIR)/libucontext_i386_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libucontext_x86_64_$(CURRENT_VARIANT).a
+IS_ZIPPERED = YES
+
+SIMULATOR_LDFLAGS =
+SIMULATOR_LDFLAGS[sdk=macosx*] = -Wl,-simulator_support
+
OTHER_LDFLAGS = $(OTHER_LDFLAGS_$(TARGET_NAME)) $(CR_LDFLAGS)
-OTHER_LDFLAGS_libsystem_platform = -all_load $(PLATFORM_LIBRARIES) -umbrella System -L/usr/lib/system -ldyld -lcompiler_rt $(lsystem_kernel) -Wl,-alias_list,$(SRCROOT)/xcodeconfig/libplatform.aliases,$(DIRTY_DATA_LDFLAGS)
+OTHER_LDFLAGS_libsystem_platform = -all_load $(PLATFORM_LIBRARIES) -umbrella System -L$(SDK_INSTALL_ROOT)/usr/lib/system -ldyld $(lcompiler_rt) $(lsystem_kernel) -Wl,-alias_list,$(SRCROOT)/xcodeconfig/libplatform.aliases,$(DIRTY_DATA_LDFLAGS) $(SIMULATOR_LDFLAGS)
OTHER_LIBTOOLFLAGS = $(OTHER_LIBTOOLFLAGS_$(TARGET_NAME))
OTHER_LIBTOOLFLAGS_libplatform_simple_dyld = $(CONFIGURATION_BUILD_DIR)/libsimple_$(CURRENT_VARIANT).a
lsystem_kernel = -lsystem_kernel
lsystem_kernel[sdk=iphonesimulator*] = -lsystem_sim_kernel
+lcompiler_rt = -lcompiler_rt
+lcompiler_rt[sdk=driverkit*] =
SRCROOT_SEARCH_PATHS = $(inherited) $(SRCROOT)/src/os/resolver
OSATOMIC_PREPROCESSOR_DEFINITIONS = OSATOMIC_USE_INLINED=0 OSATOMIC_DEPRECATED=0 OSSPINLOCK_USE_INLINED=0 OSSPINLOCK_DEPRECATED=0
-PUBLIC_HEADERS_FOLDER_PATH = /usr/include/os
-PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/os
-OS_INTERNAL_HEADERS_FOLDER_PATH = /usr/local/include/os/internal
+PUBLIC_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/include/os
+PRIVATE_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/local/include/os
+OS_INTERNAL_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/local/include/os/internal