]> git.saurik.com Git - apple/libpthread.git/commitdiff
libpthread-416.11.1.tar.gz macos-1015 v416.11.1
authorApple <opensource@apple.com>
Fri, 31 Jan 2020 01:57:10 +0000 (01:57 +0000)
committerApple <opensource@apple.com>
Fri, 31 Jan 2020 01:57:10 +0000 (01:57 +0000)
39 files changed:
kern/kern_support.c
kern/kern_synch.c
libpthread.xcodeproj/project.pbxproj
man/pthread_setname_np.3
private/private.h
private/tsd_private.h
private/workqueue_private.h
pthread/pthread.h
src/internal.h
src/pthread.c
src/pthread_asm.s
src/pthread_cancelable.c
src/pthread_cond.c
src/pthread_cwd.c
src/pthread_dependency.c
src/pthread_mutex.c
src/pthread_rwlock.c
src/pthread_support.c [deleted file]
src/pthread_tsd.c
src/qos.c
src/thread_setup.c [deleted file]
sys/qos.h
sys/qos_private.h
tests/Makefile
tests/cond_timed.c
tests/helpers/stackoverflow_crash.c [new file with mode: 0644]
tests/pthread_create_from_mach_thread.c [new file with mode: 0644]
tests/pthread_threadid_np.c
tests/setrlimit_sigsegv.c [new file with mode: 0644]
tests/stack.c
tests/stack_size.c
xcodescripts/install-codes.sh
xcodescripts/install-lldbmacros.sh
xcodescripts/install-manpages.sh
xcodescripts/install-symlinks.sh
xcodescripts/install-sys-headers.sh
xcodescripts/kext.xcconfig
xcodescripts/pthread.dirty
xcodescripts/pthread.xcconfig

index e424cceac63775df0fe150a14de1d316cd3aa847..0e576c21a59e6319ce2b365da711f259e624fe31 100644 (file)
@@ -122,12 +122,18 @@ lck_attr_t   *pthread_lck_attr;
 
 #define C_32_STK_ALIGN          16
 #define C_64_STK_ALIGN          16
 
 #define C_32_STK_ALIGN          16
 #define C_64_STK_ALIGN          16
-#define C_64_REDZONE_LEN        128
 
 // WORKQ use the largest alignment any platform needs
 #define C_WORKQ_STK_ALIGN       16
 
 
 // WORKQ use the largest alignment any platform needs
 #define C_WORKQ_STK_ALIGN       16
 
+#if defined(__arm64__)
+/* Pull the pthread_t into the same page as the top of the stack so we dirty one less page.
+ * <rdar://problem/19941744> The _pthread struct at the top of the stack shouldn't be page-aligned
+ */
+#define PTHREAD_T_OFFSET (12*1024)
+#else
 #define PTHREAD_T_OFFSET 0
 #define PTHREAD_T_OFFSET 0
+#endif
 
 /*
  * Flags filed passed to bsdthread_create and back in pthread_start
 
 /*
  * Flags filed passed to bsdthread_create and back in pthread_start
@@ -169,11 +175,13 @@ stack_addr_hint(proc_t p, vm_map_t vmap)
        mach_vm_offset_t stackaddr;
        mach_vm_offset_t aslr_offset;
        bool proc64bit = proc_is64bit(p);
        mach_vm_offset_t stackaddr;
        mach_vm_offset_t aslr_offset;
        bool proc64bit = proc_is64bit(p);
+       bool proc64bit_data = proc_is64bit_data(p);
 
        // We can't safely take random values % something unless its a power-of-two
        _Static_assert(powerof2(PTH_DEFAULT_STACKSIZE), "PTH_DEFAULT_STACKSIZE is a power-of-two");
 
 #if defined(__i386__) || defined(__x86_64__)
 
        // We can't safely take random values % something unless its a power-of-two
        _Static_assert(powerof2(PTH_DEFAULT_STACKSIZE), "PTH_DEFAULT_STACKSIZE is a power-of-two");
 
 #if defined(__i386__) || defined(__x86_64__)
+       (void)proc64bit_data;
        if (proc64bit) {
                // Matches vm_map_get_max_aslr_slide_pages's image shift in xnu
                aslr_offset = random() % (1 << 28); // about 512 stacks
        if (proc64bit) {
                // Matches vm_map_get_max_aslr_slide_pages's image shift in xnu
                aslr_offset = random() % (1 << 28); // about 512 stacks
@@ -211,7 +219,13 @@ stack_addr_hint(proc_t p, vm_map_t vmap)
                        stackaddr = SHARED_REGION_BASE_ARM64 - 64 * PTH_DEFAULT_STACKSIZE - aslr_offset;
                } else {
                        // If you try to slide down from this point, you risk ending up in memory consumed by malloc
                        stackaddr = SHARED_REGION_BASE_ARM64 - 64 * PTH_DEFAULT_STACKSIZE - aslr_offset;
                } else {
                        // If you try to slide down from this point, you risk ending up in memory consumed by malloc
-                       stackaddr = SHARED_REGION_BASE_ARM - 32 * PTH_DEFAULT_STACKSIZE + aslr_offset;
+                       if (proc64bit_data) {
+                               stackaddr = SHARED_REGION_BASE_ARM64_32;
+                       } else {
+                               stackaddr = SHARED_REGION_BASE_ARM;
+                       }
+
+                       stackaddr -= 32 * PTH_DEFAULT_STACKSIZE + aslr_offset;
                }
        }
 #else
                }
        }
 #else
@@ -308,7 +322,7 @@ _bsdthread_create(struct proc *p,
                        .r8  = (uint64_t)user_stack,   /* golang wants this */
                        .r9  = (uint64_t)flags,
 
                        .r8  = (uint64_t)user_stack,   /* golang wants this */
                        .r9  = (uint64_t)flags,
 
-                       .rsp = (uint64_t)(user_stack - C_64_REDZONE_LEN)
+                       .rsp = (uint64_t)user_stack,
                };
 
                (void)pthread_kern->thread_set_wq_state64(th, (thread_state_t)&state);
                };
 
                (void)pthread_kern->thread_set_wq_state64(th, (thread_state_t)&state);
@@ -322,7 +336,41 @@ _bsdthread_create(struct proc *p,
                        .edi = (uint32_t)user_stack,   /* golang wants this */
                        .esi = (uint32_t)flags,
 
                        .edi = (uint32_t)user_stack,   /* golang wants this */
                        .esi = (uint32_t)flags,
 
-                       .esp = (int)((vm_offset_t)(user_stack - C_32_STK_ALIGN))
+                       .esp = (uint32_t)user_stack,
+               };
+
+               (void)pthread_kern->thread_set_wq_state32(th, (thread_state_t)&state);
+       }
+#elif defined(__arm__) || defined(__arm64__)
+       if (proc_is64bit_data(p)) {
+#ifdef __arm64__
+               arm_thread_state64_t state = {
+                       .pc   = (uint64_t)pthread_kern->proc_get_threadstart(p),
+                       .x[0] = (uint64_t)user_pthread,
+                       .x[1] = (uint64_t)th_thport,
+                       .x[2] = (uint64_t)user_func,    /* golang wants this */
+                       .x[3] = (uint64_t)user_funcarg, /* golang wants this */
+                       .x[4] = (uint64_t)user_stack,   /* golang wants this */
+                       .x[5] = (uint64_t)flags,
+
+                       .sp   = (uint64_t)user_stack,
+               };
+
+               (void)pthread_kern->thread_set_wq_state64(th, (thread_state_t)&state);
+#else
+               panic("Shouldn't have a 64-bit thread on a 32-bit kernel...");
+#endif // defined(__arm64__)
+       } else {
+               arm_thread_state_t state = {
+                       .pc   = (uint32_t)pthread_kern->proc_get_threadstart(p),
+                       .r[0] = (uint32_t)user_pthread,
+                       .r[1] = (uint32_t)th_thport,
+                       .r[2] = (uint32_t)user_func,    /* golang wants this */
+                       .r[3] = (uint32_t)user_funcarg, /* golang wants this */
+                       .r[4] = (uint32_t)user_stack,   /* golang wants this */
+                       .r[5] = (uint32_t)flags,
+
+                       .sp   = (uint32_t)user_stack,
                };
 
                (void)pthread_kern->thread_set_wq_state32(th, (thread_state_t)&state);
                };
 
                (void)pthread_kern->thread_set_wq_state32(th, (thread_state_t)&state);
@@ -755,63 +803,77 @@ workq_set_register_state(proc_t p, thread_t th,
                        panic(__func__ ": thread_set_wq_state failed: %d", error);
                }
        }
                        panic(__func__ ": thread_set_wq_state failed: %d", error);
                }
        }
+#elif defined(__arm__) || defined(__arm64__)
+       if (!proc_is64bit_data(p)) {
+               arm_thread_state_t state = {
+                       .pc = (int)wqstart_fnptr,
+                       .r[0] = (unsigned int)addrs->self,
+                       .r[1] = (unsigned int)kport,
+                       .r[2] = (unsigned int)addrs->stack_bottom,
+                       .r[3] = (unsigned int)kevent_list,
+                       // will be pushed onto the stack as arg4/5
+                       .r[4] = (unsigned int)upcall_flags,
+                       .r[5] = (unsigned int)kevent_count,
+
+                       .sp = (int)(addrs->stack_top)
+               };
+
+               int error = pthread_kern->thread_set_wq_state32(th, (thread_state_t)&state);
+               if (error != KERN_SUCCESS) {
+                       panic(__func__ ": thread_set_wq_state failed: %d", error);
+               }
+       } else {
+#if defined(__arm64__)
+               arm_thread_state64_t state = {
+                       .pc = (uint64_t)wqstart_fnptr,
+                       .x[0] = (uint64_t)addrs->self,
+                       .x[1] = (uint64_t)kport,
+                       .x[2] = (uint64_t)addrs->stack_bottom,
+                       .x[3] = (uint64_t)kevent_list,
+                       .x[4] = (uint64_t)upcall_flags,
+                       .x[5] = (uint64_t)kevent_count,
+
+                       .sp = (uint64_t)((vm_offset_t)addrs->stack_top),
+               };
+
+               int error = pthread_kern->thread_set_wq_state64(th, (thread_state_t)&state);
+               if (error != KERN_SUCCESS) {
+                       panic(__func__ ": thread_set_wq_state failed: %d", error);
+               }
+#else /* defined(__arm64__) */
+               panic("Shouldn't have a 64-bit thread on a 32-bit kernel...");
+#endif /* defined(__arm64__) */
+       }
 #else
 #error setup_wqthread  not defined for this architecture
 #endif
 }
 
 #else
 #error setup_wqthread  not defined for this architecture
 #endif
 }
 
-static int
-workq_kevent(proc_t p, struct workq_thread_addrs *th_addrs, int upcall_flags,
+static inline int
+workq_kevent(proc_t p, struct workq_thread_addrs *th_addrs,
                user_addr_t eventlist, int nevents, int kevent_flags,
                user_addr_t *kevent_list_out, int *kevent_count_out)
 {
                user_addr_t eventlist, int nevents, int kevent_flags,
                user_addr_t *kevent_list_out, int *kevent_count_out)
 {
-       bool workloop = upcall_flags & WQ_FLAG_THREAD_WORKLOOP;
-       int kevent_count = WQ_KEVENT_LIST_LEN;
-       user_addr_t kevent_list = th_addrs->self - WQ_KEVENT_LIST_LEN * sizeof(struct kevent_qos_s);
-       user_addr_t kevent_id_addr = kevent_list;
-       kqueue_id_t kevent_id = -1;
        int ret;
 
        int ret;
 
-       if (workloop) {
-               /*
-                * The kevent ID goes just below the kevent list.  Sufficiently new
-                * userspace will know to look there.  Old userspace will just
-                * ignore it.
-                */
-               kevent_id_addr -= sizeof(kqueue_id_t);
-       }
+       user_addr_t kevent_list = th_addrs->self -
+                       WQ_KEVENT_LIST_LEN * sizeof(struct kevent_qos_s);
+       user_addr_t data_buf = kevent_list - WQ_KEVENT_DATA_SIZE;
+       user_size_t data_available = WQ_KEVENT_DATA_SIZE;
 
 
-       user_addr_t kevent_data_buf = kevent_id_addr - WQ_KEVENT_DATA_SIZE;
-       user_size_t kevent_data_available = WQ_KEVENT_DATA_SIZE;
-
-       if (workloop) {
-               kevent_flags |= KEVENT_FLAG_WORKLOOP;
-               ret = kevent_id_internal(p, &kevent_id,
-                               eventlist, nevents, kevent_list, kevent_count,
-                               kevent_data_buf, &kevent_data_available,
-                               kevent_flags, &kevent_count);
-               copyout(&kevent_id, kevent_id_addr, sizeof(kevent_id));
-       } else {
-               kevent_flags |= KEVENT_FLAG_WORKQ;
-               ret = kevent_qos_internal(p, -1, eventlist, nevents, kevent_list,
-                               kevent_count, kevent_data_buf, &kevent_data_available,
-                               kevent_flags, &kevent_count);
-       }
+       ret = pthread_kern->kevent_workq_internal(p, eventlist, nevents,
+                       kevent_list, WQ_KEVENT_LIST_LEN,
+                       data_buf, &data_available,
+                       kevent_flags, kevent_count_out);
 
        // squash any errors into just empty output
 
        // squash any errors into just empty output
-       if (ret != 0 || kevent_count == -1) {
+       if (ret != 0 || *kevent_count_out == -1) {
                *kevent_list_out = NULL;
                *kevent_count_out = 0;
                return ret;
        }
 
                *kevent_list_out = NULL;
                *kevent_count_out = 0;
                return ret;
        }
 
-       if (kevent_data_available == WQ_KEVENT_DATA_SIZE) {
-               workq_thread_set_top_addr(th_addrs, kevent_id_addr);
-       } else {
-               workq_thread_set_top_addr(th_addrs,
-                               kevent_data_buf + kevent_data_available);
-       }
-       *kevent_count_out = kevent_count;
+       workq_thread_set_top_addr(th_addrs, data_buf + data_available);
        *kevent_list_out = kevent_list;
        return ret;
 }
        *kevent_list_out = kevent_list;
        return ret;
 }
@@ -833,7 +895,7 @@ workq_kevent(proc_t p, struct workq_thread_addrs *th_addrs, int upcall_flags,
  * |pthread_t  | th_stackaddr + DEFAULT_STACKSIZE + guardsize + PTHREAD_STACK_OFFSET
  * |kevent list| optionally - at most WQ_KEVENT_LIST_LEN events
  * |kevent data| optionally - at most WQ_KEVENT_DATA_SIZE bytes
  * |pthread_t  | th_stackaddr + DEFAULT_STACKSIZE + guardsize + PTHREAD_STACK_OFFSET
  * |kevent list| optionally - at most WQ_KEVENT_LIST_LEN events
  * |kevent data| optionally - at most WQ_KEVENT_DATA_SIZE bytes
- * |stack gap  | bottom aligned to 16 bytes, and at least as big as stack_gap_min
+ * |stack gap  | bottom aligned to 16 bytes
  * |   STACK   |
  * |     â‡“     |
  * |           |
  * |   STACK   |
  * |     â‡“     |
  * |           |
@@ -880,8 +942,7 @@ workq_setup_thread(proc_t p, thread_t th, vm_map_t map, user_addr_t stackaddr,
                kevent_count = WORKQ_EXIT_THREAD_NKEVENT;
        } else if (upcall_flags & WQ_FLAG_THREAD_KEVENT) {
                unsigned int flags = KEVENT_FLAG_STACK_DATA | KEVENT_FLAG_IMMEDIATE;
                kevent_count = WORKQ_EXIT_THREAD_NKEVENT;
        } else if (upcall_flags & WQ_FLAG_THREAD_KEVENT) {
                unsigned int flags = KEVENT_FLAG_STACK_DATA | KEVENT_FLAG_IMMEDIATE;
-               workq_kevent(p, &th_addrs, upcall_flags, NULL, 0, flags,
-                               &kevent_list, &kevent_count);
+               workq_kevent(p, &th_addrs, NULL, 0, flags, &kevent_list, &kevent_count);
        }
 
        workq_set_register_state(p, th, &th_addrs, kport,
        }
 
        workq_set_register_state(p, th, &th_addrs, kport,
@@ -909,7 +970,7 @@ workq_handle_stack_events(proc_t p, thread_t th, vm_map_t map,
 
        unsigned int flags = KEVENT_FLAG_STACK_DATA | KEVENT_FLAG_IMMEDIATE |
                        KEVENT_FLAG_PARKING;
 
        unsigned int flags = KEVENT_FLAG_STACK_DATA | KEVENT_FLAG_IMMEDIATE |
                        KEVENT_FLAG_PARKING;
-       error = workq_kevent(p, &th_addrs, upcall_flags, events, nevents, flags,
+       error = workq_kevent(p, &th_addrs, events, nevents, flags,
                        &kevent_list, &kevent_count);
 
        if (error || kevent_count == 0) {
                        &kevent_list, &kevent_count);
 
        if (error || kevent_count == 0) {
index 7dabe413562e5a8bb30ef8a14fece8f94631359f..583bea2a65e55148dea51649f7c849c338c249f2 100644 (file)
@@ -246,7 +246,7 @@ _kwq_use_turnstile(ksyn_wait_queue_t kwq)
 #define KW_UNLOCK_PREPOST_READLOCK     0x08
 #define KW_UNLOCK_PREPOST_WRLOCK       0x20
 
 #define KW_UNLOCK_PREPOST_READLOCK     0x08
 #define KW_UNLOCK_PREPOST_WRLOCK       0x20
 
-static int ksyn_wq_hash_lookup(user_addr_t uaddr, proc_t p, int flags, ksyn_wait_queue_t *kwq, struct pthhashhead **hashptr, uint64_t *object, uint64_t *offset);
+static int ksyn_wq_hash_lookup(user_addr_t uaddr, proc_t p, int flags, ksyn_wait_queue_t *kwq, struct pthhashhead **hashptr, uint64_t object, uint64_t offset);
 static int ksyn_wqfind(user_addr_t mutex, uint32_t mgen, uint32_t ugen, uint32_t rw_wc, int flags, int wqtype , ksyn_wait_queue_t *wq);
 static void ksyn_wqrelease(ksyn_wait_queue_t mkwq, int qfreenow, int wqtype);
 static int ksyn_findobj(user_addr_t uaddr, uint64_t *objectp, uint64_t *offsetp);
 static int ksyn_wqfind(user_addr_t mutex, uint32_t mgen, uint32_t ugen, uint32_t rw_wc, int flags, int wqtype , ksyn_wait_queue_t *wq);
 static void ksyn_wqrelease(ksyn_wait_queue_t mkwq, int qfreenow, int wqtype);
 static int ksyn_findobj(user_addr_t uaddr, uint64_t *objectp, uint64_t *offsetp);
@@ -509,7 +509,7 @@ _kwq_handle_interrupted_wakeup(ksyn_wait_queue_t kwq, kwq_intr_type_t type,
 static void
 pthread_list_lock(void)
 {
 static void
 pthread_list_lock(void)
 {
-       lck_mtx_lock(pthread_list_mlock);
+       lck_mtx_lock_spin(pthread_list_mlock);
 }
 
 static void
 }
 
 static void
@@ -1553,23 +1553,17 @@ _pth_proc_hashinit(proc_t p)
 static int
 ksyn_wq_hash_lookup(user_addr_t uaddr, proc_t p, int flags,
                ksyn_wait_queue_t *out_kwq, struct pthhashhead **out_hashptr,
 static int
 ksyn_wq_hash_lookup(user_addr_t uaddr, proc_t p, int flags,
                ksyn_wait_queue_t *out_kwq, struct pthhashhead **out_hashptr,
-               uint64_t *out_object, uint64_t *out_offset)
+               uint64_t object, uint64_t offset)
 {
        int res = 0;
        ksyn_wait_queue_t kwq;
 {
        int res = 0;
        ksyn_wait_queue_t kwq;
-       uint64_t object = 0, offset = 0;
        struct pthhashhead *hashptr;
        if ((flags & PTHREAD_PSHARED_FLAGS_MASK) == PTHREAD_PROCESS_SHARED) {
                hashptr = pth_glob_hashtbl;
        struct pthhashhead *hashptr;
        if ((flags & PTHREAD_PSHARED_FLAGS_MASK) == PTHREAD_PROCESS_SHARED) {
                hashptr = pth_glob_hashtbl;
-               res = ksyn_findobj(uaddr, &object, &offset);
-               if (res == 0) {
-                       LIST_FOREACH(kwq, &hashptr[object & pthhash], kw_hash) {
-                               if (kwq->kw_object == object && kwq->kw_offset == offset) {
-                                       break;
-                               }
+               LIST_FOREACH(kwq, &hashptr[object & pthhash], kw_hash) {
+                       if (kwq->kw_object == object && kwq->kw_offset == offset) {
+                               break;
                        }
                        }
-               } else {
-                       kwq = NULL;
                }
        } else {
                hashptr = pthread_kern->proc_get_pthhash(p);
                }
        } else {
                hashptr = pthread_kern->proc_get_pthhash(p);
@@ -1580,8 +1574,6 @@ ksyn_wq_hash_lookup(user_addr_t uaddr, proc_t p, int flags,
                }
        }
        *out_kwq = kwq;
                }
        }
        *out_kwq = kwq;
-       *out_object = object;
-       *out_offset = offset;
        *out_hashptr = hashptr;
        return res;
 }
        *out_hashptr = hashptr;
        return res;
 }
@@ -1692,7 +1684,7 @@ ksyn_wqfind(user_addr_t uaddr, uint32_t mgen, uint32_t ugen, uint32_t sgen,
        while (res == 0) {
                pthread_list_lock();
                res = ksyn_wq_hash_lookup(uaddr, current_proc(), flags, &kwq, &hashptr,
        while (res == 0) {
                pthread_list_lock();
                res = ksyn_wq_hash_lookup(uaddr, current_proc(), flags, &kwq, &hashptr,
-                               &object, &offset);
+                               object, offset);
                if (res != 0) {
                        pthread_list_unlock();
                        break;
                if (res != 0) {
                        pthread_list_unlock();
                        break;
index 1c4fd1a07292ce8965a0a5ba9daf68fccd0f5044..5c193fdfa7707b10eacd3efbd17915e0c9cd287b 100644 (file)
                        name = Tests;
                        productName = Tests;
                };
                        name = Tests;
                        productName = Tests;
                };
+               C900AEA7215AF7170011B58C /* Introspection */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = C900AEAA215AF7170011B58C /* Build configuration list for PBXAggregateTarget "Introspection" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               C900AEAE215AF7290011B58C /* PBXTargetDependency */,
+                       );
+                       name = Introspection;
+                       productName = Introspection;
+               };
                C90E7AAC15DC3D3300A06D48 /* All */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = C90E7AAD15DC3D3300A06D48 /* Build configuration list for PBXAggregateTarget "All" */;
                        buildPhases = (
                        );
                        dependencies = (
                C90E7AAC15DC3D3300A06D48 /* All */ = {
                        isa = PBXAggregateTarget;
                        buildConfigurationList = C90E7AAD15DC3D3300A06D48 /* Build configuration list for PBXAggregateTarget "All" */;
                        buildPhases = (
                        );
                        dependencies = (
-                               6E8C16821B14F11800C8987C /* PBXTargetDependency */,
                                C90E7AB015DC3D3D00A06D48 /* PBXTargetDependency */,
                                C04545BC1C58510F006A53B3 /* PBXTargetDependency */,
                                C90E7AB215DC3D3D00A06D48 /* PBXTargetDependency */,
                                C90E7AB015DC3D3D00A06D48 /* PBXTargetDependency */,
                                C04545BC1C58510F006A53B3 /* PBXTargetDependency */,
                                C90E7AB215DC3D3D00A06D48 /* PBXTargetDependency */,
@@ -49,7 +59,6 @@
                        buildPhases = (
                        );
                        dependencies = (
                        buildPhases = (
                        );
                        dependencies = (
-                               6E8C16841B14F11B00C8987C /* PBXTargetDependency */,
                                C98832C615DEB44B00B3308E /* PBXTargetDependency */,
                                C04545BE1C585487006A53B3 /* PBXTargetDependency */,
                                C98832C815DEB44B00B3308E /* PBXTargetDependency */,
                                C98832C615DEB44B00B3308E /* PBXTargetDependency */,
                                C04545BE1C585487006A53B3 /* PBXTargetDependency */,
                                C98832C815DEB44B00B3308E /* PBXTargetDependency */,
                        name = Embedded;
                        productName = Embedded;
                };
                        name = Embedded;
                        productName = Embedded;
                };
+               E4B7FCA822000AF50010A840 /* libpthread_driverkit */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = E4B7FCAF22000AF50010A840 /* Build configuration list for PBXAggregateTarget "libpthread_driverkit" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               E4B7FCA922000AF50010A840 /* PBXTargetDependency */,
+                       );
+                       name = libpthread_driverkit;
+                       productName = All;
+               };
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
                6E8C16601B14F08A00C8987C /* pthread_cond_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D615C9CECA0098ECD8 /* pthread_cond_legacy.c */; };
                6E8C16611B14F08A00C8987C /* pthread_mutex_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D815C9CEEA0098ECD8 /* pthread_mutex_legacy.c */; };
                6E8C16621B14F08A00C8987C /* pthread_rwlock_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DA15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c */; };
                6E8C16601B14F08A00C8987C /* pthread_cond_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D615C9CECA0098ECD8 /* pthread_cond_legacy.c */; };
                6E8C16611B14F08A00C8987C /* pthread_mutex_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D815C9CEEA0098ECD8 /* pthread_mutex_legacy.c */; };
                6E8C16621B14F08A00C8987C /* pthread_rwlock_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DA15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c */; };
-               6E8C16631B14F08A00C8987C /* pthread_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DC15C9D16B0098ECD8 /* pthread_support.c */; };
-               6E8C16641B14F08A00C8987C /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FC15B7513200270056 /* thread_setup.c */; };
                6E8C16651B14F08A00C8987C /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                6E8C16661B14F08A00C8987C /* pthread_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C99AD87D15DF04D10009A6F8 /* pthread_asm.s */; };
                6E8C16691B14F08A00C8987C /* qos.h in Headers */ = {isa = PBXBuildFile; fileRef = C9244C1A185FCFED00075748 /* qos.h */; };
                6E8C16651B14F08A00C8987C /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                6E8C16661B14F08A00C8987C /* pthread_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C99AD87D15DF04D10009A6F8 /* pthread_asm.s */; };
                6E8C16691B14F08A00C8987C /* qos.h in Headers */ = {isa = PBXBuildFile; fileRef = C9244C1A185FCFED00075748 /* qos.h */; };
                74E594951613AAF4006C417B /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                74E594961613AAF4006C417B /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                74E594971613AAF4006C417B /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
                74E594951613AAF4006C417B /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                74E594961613AAF4006C417B /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                74E594971613AAF4006C417B /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
-               74E594981613AAF4006C417B /* pthread_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DC15C9D16B0098ECD8 /* pthread_support.c */; };
                74E594991613AAF4006C417B /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
                74E594991613AAF4006C417B /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
-               74E5949A1613AAF4006C417B /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FC15B7513200270056 /* thread_setup.c */; };
                74E5949C1613AAF4006C417B /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                74E5949E1613AAF4006C417B /* pthread_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C99AD87D15DF04D10009A6F8 /* pthread_asm.s */; };
                74E594A61613AB10006C417B /* pthread_cancelable_cancel.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A1BF5215C9A9F5006BB313 /* pthread_cancelable_cancel.c */; };
                74E5949C1613AAF4006C417B /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                74E5949E1613AAF4006C417B /* pthread_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C99AD87D15DF04D10009A6F8 /* pthread_asm.s */; };
                74E594A61613AB10006C417B /* pthread_cancelable_cancel.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A1BF5215C9A9F5006BB313 /* pthread_cancelable_cancel.c */; };
                C04545A81C584F4A006A53B3 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                C04545A91C584F4A006A53B3 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                C04545AB1C584F4A006A53B3 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
                C04545A81C584F4A006A53B3 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                C04545A91C584F4A006A53B3 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                C04545AB1C584F4A006A53B3 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
-               C04545AC1C584F4A006A53B3 /* pthread_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DC15C9D16B0098ECD8 /* pthread_support.c */; };
                C04545AD1C584F4A006A53B3 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
                C04545AD1C584F4A006A53B3 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
-               C04545AE1C584F4A006A53B3 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FC15B7513200270056 /* thread_setup.c */; };
                C04545AF1C584F4A006A53B3 /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                C04545B01C584F4A006A53B3 /* pthread_cwd.c in Sources */ = {isa = PBXBuildFile; fileRef = 924D8EDE1C11832A002AC2BC /* pthread_cwd.c */; };
                C04545B11C584F4A006A53B3 /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                C04545AF1C584F4A006A53B3 /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                C04545B01C584F4A006A53B3 /* pthread_cwd.c in Sources */ = {isa = PBXBuildFile; fileRef = 924D8EDE1C11832A002AC2BC /* pthread_cwd.c */; };
                C04545B11C584F4A006A53B3 /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                C90E7AA615DC3C9D00A06D48 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                C90E7AA715DC3C9D00A06D48 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                C90E7AA815DC3C9D00A06D48 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
                C90E7AA615DC3C9D00A06D48 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                C90E7AA715DC3C9D00A06D48 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                C90E7AA815DC3C9D00A06D48 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
-               C90E7AA915DC3C9D00A06D48 /* pthread_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DC15C9D16B0098ECD8 /* pthread_support.c */; };
                C90E7AAA15DC3C9D00A06D48 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
                C90E7AAA15DC3C9D00A06D48 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
-               C90E7AAB15DC3C9D00A06D48 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FC15B7513200270056 /* thread_setup.c */; };
                C90E7AB815DC40D900A06D48 /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                C90E7AB915DC40D900A06D48 /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                C9153096167ACC2B006BB094 /* private.h in Headers */ = {isa = PBXBuildFile; fileRef = C9153095167ACC22006BB094 /* private.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C90E7AB815DC40D900A06D48 /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                C90E7AB915DC40D900A06D48 /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                C9153096167ACC2B006BB094 /* private.h in Headers */ = {isa = PBXBuildFile; fileRef = C9153095167ACC22006BB094 /* private.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C9244C1D1860D8EF00075748 /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                C9244C1E1860D96D00075748 /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                C9244C1F1860D96E00075748 /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                C9244C1D1860D8EF00075748 /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                C9244C1E1860D96D00075748 /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                C9244C1F1860D96E00075748 /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
-               C948FCF715D1D1E100180BF5 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FC15B7513200270056 /* thread_setup.c */; };
                C975D5D715C9CECA0098ECD8 /* pthread_cond_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D615C9CECA0098ECD8 /* pthread_cond_legacy.c */; };
                C975D5D915C9CEEA0098ECD8 /* pthread_mutex_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D815C9CEEA0098ECD8 /* pthread_mutex_legacy.c */; };
                C975D5DB15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DA15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c */; };
                C975D5D715C9CECA0098ECD8 /* pthread_cond_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D615C9CECA0098ECD8 /* pthread_cond_legacy.c */; };
                C975D5D915C9CEEA0098ECD8 /* pthread_mutex_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D815C9CEEA0098ECD8 /* pthread_mutex_legacy.c */; };
                C975D5DB15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DA15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c */; };
-               C975D5DD15C9D16B0098ECD8 /* pthread_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DC15C9D16B0098ECD8 /* pthread_support.c */; };
                C98C95D918FF1F4E005654FB /* spawn.h in Headers */ = {isa = PBXBuildFile; fileRef = C98C95D818FF1F4E005654FB /* spawn.h */; settings = {ATTRIBUTES = (Public, ); }; };
                C99AD87B15DEC4BC0009A6F8 /* posix_sched.h in Headers */ = {isa = PBXBuildFile; fileRef = C9A325F015B7513200270056 /* posix_sched.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C99AD87C15DEC5290009A6F8 /* spinlock_private.h in Headers */ = {isa = PBXBuildFile; fileRef = C9A325F715B7513200270056 /* spinlock_private.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C98C95D918FF1F4E005654FB /* spawn.h in Headers */ = {isa = PBXBuildFile; fileRef = C98C95D818FF1F4E005654FB /* spawn.h */; settings = {ATTRIBUTES = (Public, ); }; };
                C99AD87B15DEC4BC0009A6F8 /* posix_sched.h in Headers */ = {isa = PBXBuildFile; fileRef = C9A325F015B7513200270056 /* posix_sched.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C99AD87C15DEC5290009A6F8 /* spinlock_private.h in Headers */ = {isa = PBXBuildFile; fileRef = C9A325F715B7513200270056 /* spinlock_private.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               C99AD87F15DF04D10009A6F8 /* pthread_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C99AD87D15DF04D10009A6F8 /* pthread_asm.s */; };
                C99AD88015E2D8B50009A6F8 /* pthread_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C99AD87D15DF04D10009A6F8 /* pthread_asm.s */; };
                C9A1BF4715C9A578006BB313 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FA15B7513200270056 /* pthread.c */; };
                C9A1BF4815C9A578006BB313 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F115B7513200270056 /* pthread_cancelable.c */; };
                C99AD88015E2D8B50009A6F8 /* pthread_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C99AD87D15DF04D10009A6F8 /* pthread_asm.s */; };
                C9A1BF4715C9A578006BB313 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FA15B7513200270056 /* pthread.c */; };
                C9A1BF4815C9A578006BB313 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F115B7513200270056 /* pthread_cancelable.c */; };
                E41505D61E818BEB00F243FB /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                E41505D71E818BEB00F243FB /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                E41505D91E818BEB00F243FB /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
                E41505D61E818BEB00F243FB /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                E41505D71E818BEB00F243FB /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                E41505D91E818BEB00F243FB /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
-               E41505DA1E818BEB00F243FB /* pthread_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DC15C9D16B0098ECD8 /* pthread_support.c */; };
                E41505DB1E818BEB00F243FB /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
                E41505DB1E818BEB00F243FB /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
-               E41505DC1E818BEB00F243FB /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FC15B7513200270056 /* thread_setup.c */; };
                E41505DD1E818BEB00F243FB /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                E41505DE1E818BEB00F243FB /* pthread_cwd.c in Sources */ = {isa = PBXBuildFile; fileRef = 924D8EDE1C11832A002AC2BC /* pthread_cwd.c */; };
                E41505DF1E818BEB00F243FB /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                E41505DD1E818BEB00F243FB /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                E41505DE1E818BEB00F243FB /* pthread_cwd.c in Sources */ = {isa = PBXBuildFile; fileRef = 924D8EDE1C11832A002AC2BC /* pthread_cwd.c */; };
                E41505DF1E818BEB00F243FB /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                E4F449921E82C1F000A7FB9A /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                E4F449931E82C1F000A7FB9A /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                E4F449941E82C1F000A7FB9A /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
                E4F449921E82C1F000A7FB9A /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F215B7513200270056 /* pthread_cond.c */; };
                E4F449931E82C1F000A7FB9A /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F515B7513200270056 /* pthread_mutex.c */; };
                E4F449941E82C1F000A7FB9A /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F615B7513200270056 /* pthread_rwlock.c */; };
-               E4F449951E82C1F000A7FB9A /* pthread_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DC15C9D16B0098ECD8 /* pthread_support.c */; };
                E4F449961E82C1F000A7FB9A /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
                E4F449961E82C1F000A7FB9A /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325F815B7513200270056 /* pthread_tsd.c */; };
-               E4F449971E82C1F000A7FB9A /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FC15B7513200270056 /* thread_setup.c */; };
                E4F449981E82C1F000A7FB9A /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                E4F449991E82C1F000A7FB9A /* pthread_cwd.c in Sources */ = {isa = PBXBuildFile; fileRef = 924D8EDE1C11832A002AC2BC /* pthread_cwd.c */; };
                E4F4499A1E82C1F000A7FB9A /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                E4F449981E82C1F000A7FB9A /* qos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9244C1C1860D8EF00075748 /* qos.c */; };
                E4F449991E82C1F000A7FB9A /* pthread_cwd.c in Sources */ = {isa = PBXBuildFile; fileRef = 924D8EDE1C11832A002AC2BC /* pthread_cwd.c */; };
                E4F4499A1E82C1F000A7FB9A /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                E4F449B51E82D03500A7FB9A /* pthread_cond_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D615C9CECA0098ECD8 /* pthread_cond_legacy.c */; };
                E4F449B61E82D03500A7FB9A /* pthread_mutex_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D815C9CEEA0098ECD8 /* pthread_mutex_legacy.c */; };
                E4F449B71E82D03500A7FB9A /* pthread_rwlock_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DA15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c */; };
                E4F449B51E82D03500A7FB9A /* pthread_cond_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D615C9CECA0098ECD8 /* pthread_cond_legacy.c */; };
                E4F449B61E82D03500A7FB9A /* pthread_mutex_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5D815C9CEEA0098ECD8 /* pthread_mutex_legacy.c */; };
                E4F449B71E82D03500A7FB9A /* pthread_rwlock_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DA15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c */; };
-               E4F449B81E82D03500A7FB9A /* pthread_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C975D5DC15C9D16B0098ECD8 /* pthread_support.c */; };
-               E4F449B91E82D03500A7FB9A /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9A325FC15B7513200270056 /* thread_setup.c */; };
                E4F449BA1E82D03500A7FB9A /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                E4F449BB1E82D03500A7FB9A /* pthread_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C99AD87D15DF04D10009A6F8 /* pthread_asm.s */; };
                E4F449BE1E82D03500A7FB9A /* qos.h in Headers */ = {isa = PBXBuildFile; fileRef = C9244C1A185FCFED00075748 /* qos.h */; settings = {ATTRIBUTES = (Public, ); }; };
                E4F449BA1E82D03500A7FB9A /* pthread_atfork.c in Sources */ = {isa = PBXBuildFile; fileRef = C90E7AB415DC40D900A06D48 /* pthread_atfork.c */; };
                E4F449BB1E82D03500A7FB9A /* pthread_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C99AD87D15DF04D10009A6F8 /* pthread_asm.s */; };
                E4F449BE1E82D03500A7FB9A /* qos.h in Headers */ = {isa = PBXBuildFile; fileRef = C9244C1A185FCFED00075748 /* qos.h */; settings = {ATTRIBUTES = (Public, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
-               6E8C16811B14F11800C8987C /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = C9A325D915B7347000270056 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 6E8C16511B14F08A00C8987C;
-                       remoteInfo = "libsystem_pthread.dylib introspection";
-               };
-               6E8C16831B14F11B00C8987C /* PBXContainerItemProxy */ = {
-                       isa = PBXContainerItemProxy;
-                       containerPortal = C9A325D915B7347000270056 /* Project object */;
-                       proxyType = 1;
-                       remoteGlobalIDString = 6E8C16511B14F08A00C8987C;
-                       remoteInfo = "libsystem_pthread.dylib introspection";
-               };
                74E594AA1613AD7F006C417B /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = C9A325D915B7347000270056 /* Project object */;
                74E594AA1613AD7F006C417B /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = C9A325D915B7347000270056 /* Project object */;
                        remoteGlobalIDString = C04545A21C584F4A006A53B3;
                        remoteInfo = "libpthread.a generic";
                };
                        remoteGlobalIDString = C04545A21C584F4A006A53B3;
                        remoteInfo = "libpthread.a generic";
                };
+               C900AEAD215AF7290011B58C /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = C9A325D915B7347000270056 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 6E8C16511B14F08A00C8987C;
+                       remoteInfo = "libsystem_pthread introspection";
+               };
                C90E7AAF15DC3D3D00A06D48 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = C9A325D915B7347000270056 /* Project object */;
                C90E7AAF15DC3D3D00A06D48 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = C9A325D915B7347000270056 /* Project object */;
                        remoteGlobalIDString = C90E7A9E15DC3C3800A06D48;
                        remoteInfo = libpthread.a;
                };
                        remoteGlobalIDString = C90E7A9E15DC3C3800A06D48;
                        remoteInfo = libpthread.a;
                };
+               E4B7FCAA22000AF50010A840 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = C9A325D915B7347000270056 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = C9A325E115B7347000270056;
+                       remoteInfo = Libpthread;
+               };
                E4F4498A1E825D2B00A7FB9A /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = C9A325D915B7347000270056 /* Project object */;
                E4F4498A1E825D2B00A7FB9A /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = C9A325D915B7347000270056 /* Project object */;
                C975D5D615C9CECA0098ECD8 /* pthread_cond_legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pthread_cond_legacy.c; sourceTree = "<group>"; };
                C975D5D815C9CEEA0098ECD8 /* pthread_mutex_legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pthread_mutex_legacy.c; sourceTree = "<group>"; };
                C975D5DA15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pthread_rwlock_legacy.c; sourceTree = "<group>"; };
                C975D5D615C9CECA0098ECD8 /* pthread_cond_legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pthread_cond_legacy.c; sourceTree = "<group>"; };
                C975D5D815C9CEEA0098ECD8 /* pthread_mutex_legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pthread_mutex_legacy.c; sourceTree = "<group>"; };
                C975D5DA15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pthread_rwlock_legacy.c; sourceTree = "<group>"; };
-               C975D5DC15C9D16B0098ECD8 /* pthread_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pthread_support.c; sourceTree = "<group>"; };
                C979E9FB18A1BC2A000951E5 /* kern_trace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = kern_trace.h; sourceTree = "<group>"; };
                C979E9FC18A2BF2C000951E5 /* install-codes.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "install-codes.sh"; sourceTree = "<group>"; };
                C98005141899BD2000368E4D /* workqueue_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = workqueue_internal.h; sourceTree = "<group>"; };
                C979E9FB18A1BC2A000951E5 /* kern_trace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = kern_trace.h; sourceTree = "<group>"; };
                C979E9FC18A2BF2C000951E5 /* install-codes.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "install-codes.sh"; sourceTree = "<group>"; };
                C98005141899BD2000368E4D /* workqueue_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = workqueue_internal.h; sourceTree = "<group>"; };
                C9A325F815B7513200270056 /* pthread_tsd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_tsd.c; sourceTree = "<group>"; };
                C9A325F915B7513200270056 /* workqueue_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = workqueue_private.h; sourceTree = "<group>"; };
                C9A325FA15B7513200270056 /* pthread.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread.c; sourceTree = "<group>"; };
                C9A325F815B7513200270056 /* pthread_tsd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_tsd.c; sourceTree = "<group>"; };
                C9A325F915B7513200270056 /* workqueue_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = workqueue_private.h; sourceTree = "<group>"; };
                C9A325FA15B7513200270056 /* pthread.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread.c; sourceTree = "<group>"; };
-               C9A325FC15B7513200270056 /* thread_setup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = thread_setup.c; sourceTree = "<group>"; };
                C9A325FE15B7513700270056 /* pthread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread.h; sourceTree = "<group>"; };
                C9A325FF15B7513700270056 /* pthread_impl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_impl.h; sourceTree = "<group>"; };
                C9A3260015B7513700270056 /* pthread_spis.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_spis.h; sourceTree = "<group>"; };
                C9A325FE15B7513700270056 /* pthread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread.h; sourceTree = "<group>"; };
                C9A325FF15B7513700270056 /* pthread_impl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_impl.h; sourceTree = "<group>"; };
                C9A3260015B7513700270056 /* pthread_spis.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_spis.h; sourceTree = "<group>"; };
                                C9A325F515B7513200270056 /* pthread_mutex.c */,
                                6E5869CA20C9043200F1CB75 /* pthread_dependency.c */,
                                C9A325F615B7513200270056 /* pthread_rwlock.c */,
                                C9A325F515B7513200270056 /* pthread_mutex.c */,
                                6E5869CA20C9043200F1CB75 /* pthread_dependency.c */,
                                C9A325F615B7513200270056 /* pthread_rwlock.c */,
-                               C975D5DC15C9D16B0098ECD8 /* pthread_support.c */,
                                C9A325F815B7513200270056 /* pthread_tsd.c */,
                                C9244C1C1860D8EF00075748 /* qos.c */,
                                C9A325F815B7513200270056 /* pthread_tsd.c */,
                                C9244C1C1860D8EF00075748 /* qos.c */,
-                               C9A325FC15B7513200270056 /* thread_setup.c */,
                                E4943AAA1E80BE1F00D2A961 /* resolver */,
                                C9A1BF5115C9A8B7006BB313 /* variants */,
                        );
                                E4943AAA1E80BE1F00D2A961 /* resolver */,
                                C9A1BF5115C9A8B7006BB313 /* variants */,
                        );
                                C90E7A9B15DC3C3800A06D48 /* Sources */,
                                C90E7A9C15DC3C3800A06D48 /* Frameworks */,
                                C90E7A9D15DC3C3800A06D48 /* Headers */,
                                C90E7A9B15DC3C3800A06D48 /* Sources */,
                                C90E7A9C15DC3C3800A06D48 /* Frameworks */,
                                C90E7A9D15DC3C3800A06D48 /* Headers */,
-                               C04545891C5844F8006A53B3 /* Symlink libpthread_dyld.a to libpthread.a */,
                        );
                        buildRules = (
                        );
                        );
                        buildRules = (
                        );
                C9A325D915B7347000270056 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
                C9A325D915B7347000270056 /* Project object */ = {
                        isa = PBXProject;
                        attributes = {
-                               LastUpgradeCheck = 0900;
+                               LastUpgradeCheck = 1100;
                                ORGANIZATIONNAME = "";
                                TargetAttributes = {
                                        92799B441B96A5FD00861404 = {
                                ORGANIZATIONNAME = "";
                                TargetAttributes = {
                                        92799B441B96A5FD00861404 = {
                                C91D01B5162892FF0002E29A /* Kext */,
                                C98832C115DEB44000B3308E /* Embedded */,
                                92799B441B96A5FD00861404 /* Tests */,
                                C91D01B5162892FF0002E29A /* Kext */,
                                C98832C115DEB44000B3308E /* Embedded */,
                                92799B441B96A5FD00861404 /* Tests */,
+                               C900AEA7215AF7170011B58C /* Introspection */,
+                               E4B7FCA822000AF50010A840 /* libpthread_driverkit */,
                                C9A325E115B7347000270056 /* libsystem_pthread */,
                                E4F449A41E82D03500A7FB9A /* libsystem_pthread noresolver */,
                                6E8C16511B14F08A00C8987C /* libsystem_pthread introspection */,
                                C9A325E115B7347000270056 /* libsystem_pthread */,
                                E4F449A41E82D03500A7FB9A /* libsystem_pthread noresolver */,
                                6E8C16511B14F08A00C8987C /* libsystem_pthread introspection */,
                        shellScript = "dtrace -h -C -s \"${SCRIPT_INPUT_FILE_0}\" -o \"${SCRIPT_OUTPUT_FILE_0}\"";
                        showEnvVarsInLog = 0;
                };
                        shellScript = "dtrace -h -C -s \"${SCRIPT_INPUT_FILE_0}\" -o \"${SCRIPT_OUTPUT_FILE_0}\"";
                        showEnvVarsInLog = 0;
                };
-               C04545891C5844F8006A53B3 /* Symlink libpthread_dyld.a to libpthread.a */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 8;
-                       files = (
-                       );
-                       inputPaths = (
-                               "$(SRCROOT)/xcodescripts/run-on-install.sh",
-                       );
-                       name = "Symlink libpthread_dyld.a to libpthread.a";
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 1;
-                       shellPath = "/bin/bash -e -x";
-                       shellScript = ". \"${SCRIPT_INPUT_FILE_0}\" /bin/ln -sf libpthread_dyld.a \"${DSTROOT}${INSTALL_PATH}/libpthread.a\"";
-                       showEnvVarsInLog = 0;
-               };
                C04545BA1C585034006A53B3 /* Symlink libpthread.a to the loaderd path */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 8;
                C04545BA1C585034006A53B3 /* Symlink libpthread.a to the loaderd path */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 8;
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = "/bin/bash -e -x";
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = "/bin/bash -e -x";
-                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-codes.sh";
+                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-codes.sh\n";
                        showEnvVarsInLog = 0;
                };
                C9A960B518452C1800AE10C8 /* Install lldbmacros */ = {
                        showEnvVarsInLog = 0;
                };
                C9A960B518452C1800AE10C8 /* Install lldbmacros */ = {
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = "/bin/bash -e -x";
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = "/bin/bash -e -x";
-                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-lldbmacros.sh";
+                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-lldbmacros.sh\n";
                        showEnvVarsInLog = 0;
                };
                C9D70EBD167AC76700D52713 /* Symlink Old Header Location */ = {
                        showEnvVarsInLog = 0;
                };
                C9D70EBD167AC76700D52713 /* Symlink Old Header Location */ = {
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = "/bin/bash -e -x";
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = "/bin/bash -e -x";
-                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-symlinks.sh";
+                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-symlinks.sh\n";
                        showEnvVarsInLog = 0;
                };
                C9DCA2A215DC4F3500D057E2 /* Install Manpages */ = {
                        showEnvVarsInLog = 0;
                };
                C9DCA2A215DC4F3500D057E2 /* Install Manpages */ = {
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = "/bin/bash -e -x";
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = "/bin/bash -e -x";
-                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-manpages.sh";
+                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-manpages.sh\n";
                        showEnvVarsInLog = 0;
                };
                E41505E31E818BEB00F243FB /* Symlink normal variant */ = {
                        showEnvVarsInLog = 0;
                };
                E41505E31E818BEB00F243FB /* Symlink normal variant */ = {
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = "/bin/bash -e -x";
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        shellPath = "/bin/bash -e -x";
-                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-sys-headers.sh";
+                       shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-sys-headers.sh\n";
                        showEnvVarsInLog = 0;
                };
 /* End PBXShellScriptBuildPhase section */
                        showEnvVarsInLog = 0;
                };
 /* End PBXShellScriptBuildPhase section */
                                6E8C16601B14F08A00C8987C /* pthread_cond_legacy.c in Sources */,
                                6E8C16611B14F08A00C8987C /* pthread_mutex_legacy.c in Sources */,
                                6E8C16621B14F08A00C8987C /* pthread_rwlock_legacy.c in Sources */,
                                6E8C16601B14F08A00C8987C /* pthread_cond_legacy.c in Sources */,
                                6E8C16611B14F08A00C8987C /* pthread_mutex_legacy.c in Sources */,
                                6E8C16621B14F08A00C8987C /* pthread_rwlock_legacy.c in Sources */,
-                               6E8C16631B14F08A00C8987C /* pthread_support.c in Sources */,
-                               6E8C16641B14F08A00C8987C /* thread_setup.c in Sources */,
                                6E8C16651B14F08A00C8987C /* pthread_atfork.c in Sources */,
                                6E5869CD20C9043B00F1CB75 /* pthread_dependency.c in Sources */,
                                6E8C16661B14F08A00C8987C /* pthread_asm.s in Sources */,
                                6E8C16651B14F08A00C8987C /* pthread_atfork.c in Sources */,
                                6E5869CD20C9043B00F1CB75 /* pthread_dependency.c in Sources */,
                                6E8C16661B14F08A00C8987C /* pthread_asm.s in Sources */,
                                74E594951613AAF4006C417B /* pthread_cond.c in Sources */,
                                74E594961613AAF4006C417B /* pthread_mutex.c in Sources */,
                                74E594971613AAF4006C417B /* pthread_rwlock.c in Sources */,
                                74E594951613AAF4006C417B /* pthread_cond.c in Sources */,
                                74E594961613AAF4006C417B /* pthread_mutex.c in Sources */,
                                74E594971613AAF4006C417B /* pthread_rwlock.c in Sources */,
-                               74E594981613AAF4006C417B /* pthread_support.c in Sources */,
                                74E594991613AAF4006C417B /* pthread_tsd.c in Sources */,
                                74E594991613AAF4006C417B /* pthread_tsd.c in Sources */,
-                               74E5949A1613AAF4006C417B /* thread_setup.c in Sources */,
                                C9244C1F1860D96E00075748 /* qos.c in Sources */,
                                924D8EDF1C11833D002AC2BC /* pthread_cwd.c in Sources */,
                                74E5949C1613AAF4006C417B /* pthread_atfork.c in Sources */,
                                C9244C1F1860D96E00075748 /* qos.c in Sources */,
                                924D8EDF1C11833D002AC2BC /* pthread_cwd.c in Sources */,
                                74E5949C1613AAF4006C417B /* pthread_atfork.c in Sources */,
                                C04545A81C584F4A006A53B3 /* pthread_cond.c in Sources */,
                                C04545A91C584F4A006A53B3 /* pthread_mutex.c in Sources */,
                                C04545AB1C584F4A006A53B3 /* pthread_rwlock.c in Sources */,
                                C04545A81C584F4A006A53B3 /* pthread_cond.c in Sources */,
                                C04545A91C584F4A006A53B3 /* pthread_mutex.c in Sources */,
                                C04545AB1C584F4A006A53B3 /* pthread_rwlock.c in Sources */,
-                               C04545AC1C584F4A006A53B3 /* pthread_support.c in Sources */,
                                C04545AD1C584F4A006A53B3 /* pthread_tsd.c in Sources */,
                                C04545AD1C584F4A006A53B3 /* pthread_tsd.c in Sources */,
-                               C04545AE1C584F4A006A53B3 /* thread_setup.c in Sources */,
                                C04545AF1C584F4A006A53B3 /* qos.c in Sources */,
                                C04545B01C584F4A006A53B3 /* pthread_cwd.c in Sources */,
                                C04545B11C584F4A006A53B3 /* pthread_atfork.c in Sources */,
                                C04545AF1C584F4A006A53B3 /* qos.c in Sources */,
                                C04545B01C584F4A006A53B3 /* pthread_cwd.c in Sources */,
                                C04545B11C584F4A006A53B3 /* pthread_atfork.c in Sources */,
                                C90E7AA715DC3C9D00A06D48 /* pthread_mutex.c in Sources */,
                                6E5869D120C9043D00F1CB75 /* pthread_dependency.c in Sources */,
                                C90E7AA815DC3C9D00A06D48 /* pthread_rwlock.c in Sources */,
                                C90E7AA715DC3C9D00A06D48 /* pthread_mutex.c in Sources */,
                                6E5869D120C9043D00F1CB75 /* pthread_dependency.c in Sources */,
                                C90E7AA815DC3C9D00A06D48 /* pthread_rwlock.c in Sources */,
-                               C90E7AA915DC3C9D00A06D48 /* pthread_support.c in Sources */,
                                C90E7AAA15DC3C9D00A06D48 /* pthread_tsd.c in Sources */,
                                C90E7AAA15DC3C9D00A06D48 /* pthread_tsd.c in Sources */,
-                               C90E7AAB15DC3C9D00A06D48 /* thread_setup.c in Sources */,
                                924D8EE01C11833D002AC2BC /* pthread_cwd.c in Sources */,
                                C90E7AB915DC40D900A06D48 /* pthread_atfork.c in Sources */,
                                924D8EE01C11833D002AC2BC /* pthread_cwd.c in Sources */,
                                C90E7AB915DC40D900A06D48 /* pthread_atfork.c in Sources */,
-                               C99AD87F15DF04D10009A6F8 /* pthread_asm.s in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                C975D5D715C9CECA0098ECD8 /* pthread_cond_legacy.c in Sources */,
                                C975D5D915C9CEEA0098ECD8 /* pthread_mutex_legacy.c in Sources */,
                                C975D5DB15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c in Sources */,
                                C975D5D715C9CECA0098ECD8 /* pthread_cond_legacy.c in Sources */,
                                C975D5D915C9CEEA0098ECD8 /* pthread_mutex_legacy.c in Sources */,
                                C975D5DB15C9CEFA0098ECD8 /* pthread_rwlock_legacy.c in Sources */,
-                               C975D5DD15C9D16B0098ECD8 /* pthread_support.c in Sources */,
-                               C948FCF715D1D1E100180BF5 /* thread_setup.c in Sources */,
                                C90E7AB815DC40D900A06D48 /* pthread_atfork.c in Sources */,
                                6E5869CB20C9043200F1CB75 /* pthread_dependency.c in Sources */,
                                C99AD88015E2D8B50009A6F8 /* pthread_asm.s in Sources */,
                                C90E7AB815DC40D900A06D48 /* pthread_atfork.c in Sources */,
                                6E5869CB20C9043200F1CB75 /* pthread_dependency.c in Sources */,
                                C99AD88015E2D8B50009A6F8 /* pthread_asm.s in Sources */,
                                E41505D61E818BEB00F243FB /* pthread_cond.c in Sources */,
                                E41505D71E818BEB00F243FB /* pthread_mutex.c in Sources */,
                                E41505D91E818BEB00F243FB /* pthread_rwlock.c in Sources */,
                                E41505D61E818BEB00F243FB /* pthread_cond.c in Sources */,
                                E41505D71E818BEB00F243FB /* pthread_mutex.c in Sources */,
                                E41505D91E818BEB00F243FB /* pthread_rwlock.c in Sources */,
-                               E41505DA1E818BEB00F243FB /* pthread_support.c in Sources */,
                                E41505DB1E818BEB00F243FB /* pthread_tsd.c in Sources */,
                                E41505DB1E818BEB00F243FB /* pthread_tsd.c in Sources */,
-                               E41505DC1E818BEB00F243FB /* thread_setup.c in Sources */,
                                E41505DD1E818BEB00F243FB /* qos.c in Sources */,
                                E41505DE1E818BEB00F243FB /* pthread_cwd.c in Sources */,
                                E41505DF1E818BEB00F243FB /* pthread_atfork.c in Sources */,
                                E41505DD1E818BEB00F243FB /* qos.c in Sources */,
                                E41505DE1E818BEB00F243FB /* pthread_cwd.c in Sources */,
                                E41505DF1E818BEB00F243FB /* pthread_atfork.c in Sources */,
                                E4F449921E82C1F000A7FB9A /* pthread_cond.c in Sources */,
                                E4F449931E82C1F000A7FB9A /* pthread_mutex.c in Sources */,
                                E4F449941E82C1F000A7FB9A /* pthread_rwlock.c in Sources */,
                                E4F449921E82C1F000A7FB9A /* pthread_cond.c in Sources */,
                                E4F449931E82C1F000A7FB9A /* pthread_mutex.c in Sources */,
                                E4F449941E82C1F000A7FB9A /* pthread_rwlock.c in Sources */,
-                               E4F449951E82C1F000A7FB9A /* pthread_support.c in Sources */,
                                E4F449961E82C1F000A7FB9A /* pthread_tsd.c in Sources */,
                                E4F449961E82C1F000A7FB9A /* pthread_tsd.c in Sources */,
-                               E4F449971E82C1F000A7FB9A /* thread_setup.c in Sources */,
                                E4F449981E82C1F000A7FB9A /* qos.c in Sources */,
                                E4F449991E82C1F000A7FB9A /* pthread_cwd.c in Sources */,
                                E4F4499A1E82C1F000A7FB9A /* pthread_atfork.c in Sources */,
                                E4F449981E82C1F000A7FB9A /* qos.c in Sources */,
                                E4F449991E82C1F000A7FB9A /* pthread_cwd.c in Sources */,
                                E4F4499A1E82C1F000A7FB9A /* pthread_atfork.c in Sources */,
                                E4F449B51E82D03500A7FB9A /* pthread_cond_legacy.c in Sources */,
                                E4F449B61E82D03500A7FB9A /* pthread_mutex_legacy.c in Sources */,
                                E4F449B71E82D03500A7FB9A /* pthread_rwlock_legacy.c in Sources */,
                                E4F449B51E82D03500A7FB9A /* pthread_cond_legacy.c in Sources */,
                                E4F449B61E82D03500A7FB9A /* pthread_mutex_legacy.c in Sources */,
                                E4F449B71E82D03500A7FB9A /* pthread_rwlock_legacy.c in Sources */,
-                               E4F449B81E82D03500A7FB9A /* pthread_support.c in Sources */,
-                               E4F449B91E82D03500A7FB9A /* thread_setup.c in Sources */,
                                E4F449BA1E82D03500A7FB9A /* pthread_atfork.c in Sources */,
                                6E5869CC20C9043B00F1CB75 /* pthread_dependency.c in Sources */,
                                E4F449BB1E82D03500A7FB9A /* pthread_asm.s in Sources */,
                                E4F449BA1E82D03500A7FB9A /* pthread_atfork.c in Sources */,
                                6E5869CC20C9043B00F1CB75 /* pthread_dependency.c in Sources */,
                                E4F449BB1E82D03500A7FB9A /* pthread_asm.s in Sources */,
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
-               6E8C16821B14F11800C8987C /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 6E8C16511B14F08A00C8987C /* libsystem_pthread introspection */;
-                       targetProxy = 6E8C16811B14F11800C8987C /* PBXContainerItemProxy */;
-               };
-               6E8C16841B14F11B00C8987C /* PBXTargetDependency */ = {
-                       isa = PBXTargetDependency;
-                       target = 6E8C16511B14F08A00C8987C /* libsystem_pthread introspection */;
-                       targetProxy = 6E8C16831B14F11B00C8987C /* PBXContainerItemProxy */;
-               };
                74E594AB1613AD7F006C417B /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 74E594911613AAF4006C417B /* libpthread eOS */;
                74E594AB1613AD7F006C417B /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = 74E594911613AAF4006C417B /* libpthread eOS */;
                        target = C04545A21C584F4A006A53B3 /* libpthread generic */;
                        targetProxy = C04545BD1C585487006A53B3 /* PBXContainerItemProxy */;
                };
                        target = C04545A21C584F4A006A53B3 /* libpthread generic */;
                        targetProxy = C04545BD1C585487006A53B3 /* PBXContainerItemProxy */;
                };
+               C900AEAE215AF7290011B58C /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 6E8C16511B14F08A00C8987C /* libsystem_pthread introspection */;
+                       targetProxy = C900AEAD215AF7290011B58C /* PBXContainerItemProxy */;
+               };
                C90E7AB015DC3D3D00A06D48 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = C9A325E115B7347000270056 /* libsystem_pthread */;
                C90E7AB015DC3D3D00A06D48 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = C9A325E115B7347000270056 /* libsystem_pthread */;
                        target = C90E7A9E15DC3C3800A06D48 /* libpthread dyld */;
                        targetProxy = C98832C715DEB44B00B3308E /* PBXContainerItemProxy */;
                };
                        target = C90E7A9E15DC3C3800A06D48 /* libpthread dyld */;
                        targetProxy = C98832C715DEB44B00B3308E /* PBXContainerItemProxy */;
                };
+               E4B7FCA922000AF50010A840 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = C9A325E115B7347000270056 /* libsystem_pthread */;
+                       targetProxy = E4B7FCAA22000AF50010A840 /* PBXContainerItemProxy */;
+               };
                E4F4498B1E825D2B00A7FB9A /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = E41505D01E818BEB00F243FB /* libpthread mp resolved */;
                E4F4498B1E825D2B00A7FB9A /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        target = E41505D01E818BEB00F243FB /* libpthread mp resolved */;
                        };
                        name = Release;
                };
                        };
                        name = Release;
                };
+               C900AEAB215AF7170011B58C /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                       };
+                       name = Release;
+               };
+               C900AEAC215AF7170011B58C /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                       };
+                       name = Debug;
+               };
                C90E7AA015DC3C3800A06D48 /* Release */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = C04545B91C584F8B006A53B3 /* static.xcconfig */;
                C90E7AA015DC3C3800A06D48 /* Release */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = C04545B91C584F8B006A53B3 /* static.xcconfig */;
                        };
                        name = Debug;
                };
                        };
                        name = Debug;
                };
+               E4B7FCB022000AF50010A840 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               E4B7FCB122000AF50010A840 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
                E4F4499E1E82C1F000A7FB9A /* Release */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = E41505E81E818D4D00F243FB /* resolved.xcconfig */;
                E4F4499E1E82C1F000A7FB9A /* Release */ = {
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = E41505E81E818D4D00F243FB /* resolved.xcconfig */;
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               C900AEAA215AF7170011B58C /* Build configuration list for PBXAggregateTarget "Introspection" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               C900AEAB215AF7170011B58C /* Release */,
+                               C900AEAC215AF7170011B58C /* Debug */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                C90E7AA115DC3C3800A06D48 /* Build configuration list for PBXNativeTarget "libpthread dyld" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                C90E7AA115DC3C3800A06D48 /* Build configuration list for PBXNativeTarget "libpthread dyld" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               E4B7FCAF22000AF50010A840 /* Build configuration list for PBXAggregateTarget "libpthread_driverkit" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               E4B7FCB022000AF50010A840 /* Release */,
+                               E4B7FCB122000AF50010A840 /* Debug */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
                E4F4499D1E82C1F000A7FB9A /* Build configuration list for PBXNativeTarget "libpthread armv81 resolved" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                E4F4499D1E82C1F000A7FB9A /* Build configuration list for PBXNativeTarget "libpthread armv81 resolved" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
index 13a9108f9f6c979c76b6076f68997c4ced4a9784..502e93652ddc9f4ee77ef806e7003726266cd55c 100644 (file)
@@ -36,7 +36,7 @@
 .Fn pthread_setname_np "const char *name"
 .Sh DESCRIPTION
 The
 .Fn pthread_setname_np "const char *name"
 .Sh DESCRIPTION
 The
-.Fn pthread_set_name_np
+.Fn pthread_setname_np
 function sets the internal name for the calling thread to string value specified by
 .Fa name
 argument.
 function sets the internal name for the calling thread to string value specified by
 .Fa name
 argument.
index b321442be2f0e9fe0f65c0a3d8c12ab6b6e32762..33d5e2534cbc4026f12ecc500ea6d78cdfaf0438 100644 (file)
@@ -63,6 +63,9 @@ struct _libpthread_functions {
  * If this is used on a workqueue (dispatch) thread, it MUST be unset with
  * pthread_fchdir_np(-1) before returning.
  *
  * If this is used on a workqueue (dispatch) thread, it MUST be unset with
  * pthread_fchdir_np(-1) before returning.
  *
+ * posix_spawn_file_actions_addchdir_np is a better approach if this call would
+ * only be used to spawn a new process with a given working directory.
+ *
  * @param path
  * The path of the new working directory.
  *
  * @param path
  * The path of the new working directory.
  *
@@ -70,7 +73,7 @@ struct _libpthread_functions {
  * 0 upon success, -1 upon error and errno is set.
  */
 __API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
  * 0 upon success, -1 upon error and errno is set.
  */
 __API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
-int pthread_chdir_np(char *path);
+int pthread_chdir_np(const char *path);
 
 /*!
  * @function pthread_fchdir_np
 
 /*!
  * @function pthread_fchdir_np
@@ -83,6 +86,9 @@ int pthread_chdir_np(char *path);
  * directory fd.  If this is used on a workqueue (dispatch) thread, it MUST be
  * unset with pthread_fchdir_np(-1) before returning.
  *
  * directory fd.  If this is used on a workqueue (dispatch) thread, it MUST be
  * unset with pthread_fchdir_np(-1) before returning.
  *
+ * posix_spawn_file_actions_addfchdir_np is a better approach if this call would
+ * only be used to spawn a new process with a given working directory.
+ *
  * @param fd
  * A file descriptor to the new working directory.  Pass -1 to unset the
  * per-thread working directory.
  * @param fd
  * A file descriptor to the new working directory.  Pass -1 to unset the
  * per-thread working directory.
@@ -96,6 +102,9 @@ int pthread_fchdir_np(int fd);
 __API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
 int pthread_attr_setcpupercent_np(pthread_attr_t * __restrict, int, unsigned long);
 
 __API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
 int pthread_attr_setcpupercent_np(pthread_attr_t * __restrict, int, unsigned long);
 
+__API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0), watchos(6.0))
+int pthread_current_stack_contains_np(const void *, size_t);
+
 #ifdef _os_tsd_get_base
 
 #ifdef __LP64__
 #ifdef _os_tsd_get_base
 
 #ifdef __LP64__
index 4b48d58b9f7714ce35ef01cc5d7991f484e5b5ae..e83ea66e61ad4a11d5daf95b3a5de4e30d798a34 100644 (file)
 #define __PTK_FRAMEWORK_SWIFT_KEY8             108
 #define __PTK_FRAMEWORK_SWIFT_KEY9             109
 
 #define __PTK_FRAMEWORK_SWIFT_KEY8             108
 #define __PTK_FRAMEWORK_SWIFT_KEY9             109
 
+/* Keys 190 - 194 are for the use of PerfUtils */
+#define __PTK_PERF_UTILS_KEY0          190
+#define __PTK_PERF_UTILS_KEY1          191
+#define __PTK_PERF_UTILS_KEY2          192
+#define __PTK_PERF_UTILS_KEY3          193
+#define __PTK_PERF_UTILS_KEY4          194
+
 /* Keys 210 - 229 are for libSystem usage within the iOS Simulator */
 /* They are offset from their corresponding libSystem keys by 200 */
 #define __PTK_LIBC_SIM_LOCALE_KEY      210
 /* Keys 210 - 229 are for libSystem usage within the iOS Simulator */
 /* They are offset from their corresponding libSystem keys by 200 */
 #define __PTK_LIBC_SIM_LOCALE_KEY      210
index 9cd0e951d6df271b6fbb472a48d552a7b3572436..11b0e5e143b565b685b34d4b6defe52dadb37d55 100644 (file)
@@ -74,6 +74,23 @@ typedef void (*pthread_workqueue_function_kevent_t)(void **events, int *nevents)
 
 typedef void (*pthread_workqueue_function_workloop_t)(uint64_t *workloop_id, void **events, int *nevents);
 
 
 typedef void (*pthread_workqueue_function_workloop_t)(uint64_t *workloop_id, void **events, int *nevents);
 
+#define PTHREAD_WORKQUEUE_CONFIG_VERSION               2
+#define PTHREAD_WORKQUEUE_CONFIG_MIN_SUPPORTED_VERSION 1
+#define PTHREAD_WORKQUEUE_CONFIG_SUPPORTED_FLAGS       0
+struct pthread_workqueue_config {
+       uint32_t flags;
+       uint32_t version;
+       pthread_workqueue_function_kevent_t kevent_cb;
+       pthread_workqueue_function_workloop_t workloop_cb;
+       pthread_workqueue_function2_t workq_cb;
+       uint64_t queue_serialno_offs;
+       uint64_t queue_label_offs;
+};
+
+__API_AVAILABLE(macos(10.15), ios(13.0))
+int
+pthread_workqueue_setup(struct pthread_workqueue_config *cfg, size_t cfg_size);
+
 // Initialises the pthread workqueue subsystem, passing the new-style callback prototype,
 // the dispatchoffset and an unused flags field.
 __API_AVAILABLE(macos(10.10), ios(8.0))
 // Initialises the pthread workqueue subsystem, passing the new-style callback prototype,
 // the dispatchoffset and an unused flags field.
 __API_AVAILABLE(macos(10.10), ios(8.0))
index f5fdff6b7e126f635b7204b0779a15be08c320c3..a042c82aed0c273022038e80cf9075b66f98357a 100644 (file)
@@ -188,7 +188,7 @@ __BEGIN_DECLS
 #define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}}
 
 /* <rdar://problem/10854763> */
 #define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}}
 
 /* <rdar://problem/10854763> */
-#if ((__MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000))
+#if ((__MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000)) || defined(__DRIVERKIT_VERSION_MIN_REQUIRED)
 #      if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE)
 #              define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER {_PTHREAD_ERRORCHECK_MUTEX_SIG_init, {0}}
 #              define PTHREAD_RECURSIVE_MUTEX_INITIALIZER {_PTHREAD_RECURSIVE_MUTEX_SIG_init, {0}}
 #      if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE)
 #              define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER {_PTHREAD_ERRORCHECK_MUTEX_SIG_init, {0}}
 #              define PTHREAD_RECURSIVE_MUTEX_INITIALIZER {_PTHREAD_RECURSIVE_MUTEX_SIG_init, {0}}
index e8cc16158aec17e3882f1d5166027c56e891b286..daa2179040879b42efa5880e36e4d99e38e8e7fb 100644 (file)
@@ -81,6 +81,7 @@ typedef struct _pthread_attr_t pthread_attr_t;
 #error Unsupported target
 #endif
 
 #error Unsupported target
 #endif
 
+
 #define PTHREAD_INTERNAL_CRASH(c, x) do { \
                _os_set_crash_log_cause_and_message((c), \
                                "BUG IN LIBPTHREAD: " x); \
 #define PTHREAD_INTERNAL_CRASH(c, x) do { \
                _os_set_crash_log_cause_and_message((c), \
                                "BUG IN LIBPTHREAD: " x); \
@@ -160,7 +161,14 @@ PTHREAD_NOEXPORT extern uint64_t _pthread_debugstart;
 #define _INTERNAL_POSIX_THREAD_KEYS_END 768
 #endif
 
 #define _INTERNAL_POSIX_THREAD_KEYS_END 768
 #endif
 
+#if defined(__arm64__)
+/* Pull the pthread_t into the same page as the top of the stack so we dirty one less page.
+ * <rdar://problem/19941744> The _pthread struct at the top of the stack shouldn't be page-aligned
+ */
+#define PTHREAD_T_OFFSET (12*1024)
+#else
 #define PTHREAD_T_OFFSET 0
 #define PTHREAD_T_OFFSET 0
+#endif
 
 #define MAXTHREADNAMESIZE      64
 #define _PTHREAD_T
 
 #define MAXTHREADNAMESIZE      64
 #define _PTHREAD_T
@@ -192,6 +200,7 @@ typedef struct _pthread {
        // MACH_PORT_DEAD if the thread exited
        uint32_t tl_exit_gate;
        struct sched_param tl_param;
        // MACH_PORT_DEAD if the thread exited
        uint32_t tl_exit_gate;
        struct sched_param tl_param;
+       void *__unused_padding;
 
        //
        // Fields protected by pthread_t::lock
 
        //
        // Fields protected by pthread_t::lock
@@ -204,18 +213,16 @@ typedef struct _pthread {
                        schedset:1,
                        wqthread:1,
                        wqkillset:1,
                        schedset:1,
                        wqthread:1,
                        wqkillset:1,
-                       wqoutsideqos:1,
-                       __flags_pad:3;
+                       __flags_pad:4;
 
        char pthread_name[MAXTHREADNAMESIZE];   // includes NUL [aligned]
 
        void *(*fun)(void *);   // thread start routine
 
        char pthread_name[MAXTHREADNAMESIZE];   // includes NUL [aligned]
 
        void *(*fun)(void *);   // thread start routine
-       void *wq_kqid_ptr;              // wqthreads (workloop)
        void *arg;                              // thread start routine argument
        int   wq_nevents;               // wqthreads (workloop / kevent)
        void *arg;                              // thread start routine argument
        int   wq_nevents;               // wqthreads (workloop / kevent)
-       uint16_t wq_retop;              // wqthreads
-       uint8_t cancel_state;   // whether the thread can be canceled [atomic]
+       bool  wq_outsideqos;
        uint8_t canceled;               // 4597450 set if conformant cancelation happened
        uint8_t canceled;               // 4597450 set if conformant cancelation happened
+       uint16_t cancel_state;  // whether the thread can be canceled [atomic]
        errno_t cancel_error;
        errno_t err_no;                 // thread-local errno
 
        errno_t cancel_error;
        errno_t err_no;                 // thread-local errno
 
@@ -467,7 +474,6 @@ _pthread_selfid_direct(void)
 #define _PTHREAD_CANCEL_STATE_MASK   0x01
 #define _PTHREAD_CANCEL_TYPE_MASK    0x02
 #define _PTHREAD_CANCEL_PENDING             0x10  /* pthread_cancel() has been called for this thread */
 #define _PTHREAD_CANCEL_STATE_MASK   0x01
 #define _PTHREAD_CANCEL_TYPE_MASK    0x02
 #define _PTHREAD_CANCEL_PENDING             0x10  /* pthread_cancel() has been called for this thread */
-#define _PTHREAD_CANCEL_INITIALIZED  0x20  /* the thread in the list is properly initialized */
 
 extern boolean_t swtch_pri(int);
 
 
 extern boolean_t swtch_pri(int);
 
@@ -510,14 +516,6 @@ PTHREAD_NOEXPORT
 void
 _pthread_deallocate(pthread_t t, bool from_mach_thread);
 
 void
 _pthread_deallocate(pthread_t t, bool from_mach_thread);
 
-PTHREAD_NORETURN PTHREAD_NOEXPORT
-void
-__pthread_abort(void);
-
-PTHREAD_NORETURN PTHREAD_NOEXPORT
-void
-__pthread_abort_reason(const char *fmt, ...) __printflike(1,2);
-
 PTHREAD_NOEXPORT
 thread_qos_t
 _pthread_qos_class_to_thread_qos(qos_class_t qos);
 PTHREAD_NOEXPORT
 thread_qos_t
 _pthread_qos_class_to_thread_qos(qos_class_t qos);
@@ -538,7 +536,7 @@ PTHREAD_EXPORT
 void
 _pthread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int flags);
 
 void
 _pthread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int flags);
 
-PTHREAD_NORETURN PTHREAD_EXPORT
+PTHREAD_EXPORT
 void
 _pthread_wqthread(pthread_t self, mach_port_t kport, void *stackaddr, void *keventlist, int flags, int nkevents);
 
 void
 _pthread_wqthread(pthread_t self, mach_port_t kport, void *stackaddr, void *keventlist, int flags, int nkevents);
 
@@ -596,11 +594,16 @@ _pthread_set_kernel_thread(pthread_t t, mach_port_t p)
        t->tsd[_PTHREAD_TSD_SLOT_MACH_THREAD_SELF] = p;
 }
 
        t->tsd[_PTHREAD_TSD_SLOT_MACH_THREAD_SELF] = p;
 }
 
-#define PTHREAD_ABORT(f,...) __pthread_abort_reason( \
-               "%s:%s:%u: " f, __FILE__, __func__, __LINE__, ## __VA_ARGS__)
-
-#define PTHREAD_ASSERT(b) \
-               do { if (!(b)) PTHREAD_ABORT("failed assertion `%s'", #b); } while (0)
+#ifdef DEBUG
+#define PTHREAD_DEBUG_ASSERT(b) \
+               do { \
+                       if (os_unlikely(!(b))) { \
+                               PTHREAD_INTERNAL_CRASH(0, "Assertion failed: " #b); \
+                       } \
+               } while (0)
+#else
+#define PTHREAD_DEBUG_ASSERT(b) ((void)0)
+#endif
 
 #include <os/semaphore_private.h>
 #include <os/alloc_once_private.h>
 
 #include <os/semaphore_private.h>
 #include <os/alloc_once_private.h>
@@ -690,21 +693,13 @@ _pthread_validate_thread_and_list_lock(pthread_t thread)
 {
        pthread_t p;
        if (thread == NULL) return false;
 {
        pthread_t p;
        if (thread == NULL) return false;
-loop:
        _PTHREAD_LOCK(_pthread_list_lock);
        TAILQ_FOREACH(p, &__pthread_head, tl_plist) {
                if (p != thread) continue;
        _PTHREAD_LOCK(_pthread_list_lock);
        TAILQ_FOREACH(p, &__pthread_head, tl_plist) {
                if (p != thread) continue;
-               int state = os_atomic_load(&p->cancel_state, relaxed);
-               if (os_likely(state & _PTHREAD_CANCEL_INITIALIZED)) {
-                       if (os_unlikely(p->sig != _PTHREAD_SIG)) {
-                               PTHREAD_CLIENT_CRASH(0, "pthread_t was corrupted");
-                       }
-                       return true;
+               if (os_unlikely(p->sig != _PTHREAD_SIG)) {
+                       PTHREAD_CLIENT_CRASH(0, "pthread_t was corrupted");
                }
                }
-               _PTHREAD_UNLOCK(_pthread_list_lock);
-               thread_switch(_pthread_kernel_thread(p),
-                                         SWITCH_OPTION_OSLOCK_DEPRESS, 1);
-               goto loop;
+               return true;
        }
        _PTHREAD_UNLOCK(_pthread_list_lock);
 
        }
        _PTHREAD_UNLOCK(_pthread_list_lock);
 
index 3c3ea6a02645a2a1d6ad3e3ab27d0fbc640f69fa..8eca496e496194d7436954bfbc69798d8a9631da 100644 (file)
 #include <machine/vmparam.h>
 #define        __APPLE_API_PRIVATE
 #include <machine/cpu_capabilities.h>
 #include <machine/vmparam.h>
 #define        __APPLE_API_PRIVATE
 #include <machine/cpu_capabilities.h>
+#if __has_include(<ptrauth.h>)
+#include <ptrauth.h>
+#endif // __has_include(<ptrauth.h>)
 
 #include <_simple.h>
 #include <platform/string.h>
 #include <platform/compat.h>
 
 
 #include <_simple.h>
 #include <platform/string.h>
 #include <platform/compat.h>
 
+#include <stack_logging.h>
+
+// Defined in libsyscall; initialized in libmalloc
+extern malloc_logger_t *__syscall_logger;
+
 extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
                void *newp, size_t newlen);
 extern void __exit(int) __attribute__((noreturn));
 extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
                void *newp, size_t newlen);
 extern void __exit(int) __attribute__((noreturn));
@@ -203,11 +211,12 @@ __pthread_invalid_workloopfunction(uint64_t *workloop_id, void **events, int *ne
 static pthread_workqueue_function2_t __libdispatch_workerfunction;
 static pthread_workqueue_function_kevent_t __libdispatch_keventfunction = &__pthread_invalid_keventfunction;
 static pthread_workqueue_function_workloop_t __libdispatch_workloopfunction = &__pthread_invalid_workloopfunction;
 static pthread_workqueue_function2_t __libdispatch_workerfunction;
 static pthread_workqueue_function_kevent_t __libdispatch_keventfunction = &__pthread_invalid_keventfunction;
 static pthread_workqueue_function_workloop_t __libdispatch_workloopfunction = &__pthread_invalid_workloopfunction;
-static int __libdispatch_offset;
 static int __pthread_supported_features; // supported feature set
 
 #if defined(__i386__) || defined(__x86_64__)
 static mach_vm_address_t __pthread_stack_hint = 0xB0000000;
 static int __pthread_supported_features; // supported feature set
 
 #if defined(__i386__) || defined(__x86_64__)
 static mach_vm_address_t __pthread_stack_hint = 0xB0000000;
+#elif defined(__arm__) || defined(__arm64__)
+static mach_vm_address_t __pthread_stack_hint = 0x30000000;
 #else
 #error no __pthread_stack_hint for this architecture
 #endif
 #else
 #error no __pthread_stack_hint for this architecture
 #endif
@@ -223,7 +232,7 @@ static inline void _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs
 #if VARIANT_DYLD
 static void _pthread_set_self_dyld(void);
 #endif // VARIANT_DYLD
 #if VARIANT_DYLD
 static void _pthread_set_self_dyld(void);
 #endif // VARIANT_DYLD
-static inline void _pthread_set_self_internal(pthread_t, bool needs_tsd_base_set);
+static inline void _pthread_set_self_internal(pthread_t);
 
 static void _pthread_dealloc_reply_port(pthread_t t);
 static void _pthread_dealloc_special_reply_port(pthread_t t);
 
 static void _pthread_dealloc_reply_port(pthread_t t);
 static void _pthread_dealloc_special_reply_port(pthread_t t);
@@ -259,11 +268,6 @@ extern void thread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *)
 #define PTHREAD_START_POLICY_MASK 0xff
 #define PTHREAD_START_IMPORTANCE_MASK 0xffff
 
 #define PTHREAD_START_POLICY_MASK 0xff
 #define PTHREAD_START_IMPORTANCE_MASK 0xffff
 
-#if (!defined(__OPEN_SOURCE__) && TARGET_OS_OSX) || OS_VARIANT_RESOLVED // 40703288
-static int pthread_setschedparam_internal(pthread_t, mach_port_t, int,
-               const struct sched_param *);
-#endif
-
 extern pthread_t __bsdthread_create(void *(*func)(void *), void * func_arg, void * stack, pthread_t  thread, unsigned int flags);
 extern int __bsdthread_register(void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), void (*)(pthread_t, mach_port_t, void *, void *, int), int,void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), int32_t *,__uint64_t);
 extern int __bsdthread_terminate(void * freeaddr, size_t freesize, mach_port_t kport, mach_port_t joinsem);
 extern pthread_t __bsdthread_create(void *(*func)(void *), void * func_arg, void * stack, pthread_t  thread, unsigned int flags);
 extern int __bsdthread_register(void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), void (*)(pthread_t, mach_port_t, void *, void *, int), int,void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), int32_t *,__uint64_t);
 extern int __bsdthread_terminate(void * freeaddr, size_t freesize, mach_port_t kport, mach_port_t joinsem);
@@ -584,20 +588,26 @@ pthread_attr_setcpupercent_np(pthread_attr_t *attr, int percent,
 // it should be freed.
 
 static pthread_t
 // it should be freed.
 
 static pthread_t
-_pthread_allocate(const pthread_attr_t *attrs, void **stack)
+_pthread_allocate(const pthread_attr_t *attrs, void **stack,
+               bool from_mach_thread)
 {
        mach_vm_address_t allocaddr = __pthread_stack_hint;
        size_t allocsize, guardsize, stacksize, pthreadoff;
        kern_return_t kr;
        pthread_t t;
 
 {
        mach_vm_address_t allocaddr = __pthread_stack_hint;
        size_t allocsize, guardsize, stacksize, pthreadoff;
        kern_return_t kr;
        pthread_t t;
 
-       PTHREAD_ASSERT(attrs->stacksize == 0 ||
-                       attrs->stacksize >= PTHREAD_STACK_MIN);
+       if (os_unlikely(attrs->stacksize != 0 &&
+                       attrs->stacksize < PTHREAD_STACK_MIN)) {
+               PTHREAD_CLIENT_CRASH(attrs->stacksize, "Stack size in attrs is too small");
+       }
+
+       if (os_unlikely(((uintptr_t)attrs->stackaddr % vm_page_size) != 0)) {
+               PTHREAD_CLIENT_CRASH(attrs->stacksize, "Unaligned stack addr in attrs");
+       }
 
        // Allocate a pthread structure if necessary
 
        if (attrs->stackaddr != NULL) {
 
        // Allocate a pthread structure if necessary
 
        if (attrs->stackaddr != NULL) {
-               PTHREAD_ASSERT(((uintptr_t)attrs->stackaddr % vm_page_size) == 0);
                allocsize = PTHREAD_SIZE;
                guardsize = 0;
                pthreadoff = 0;
                allocsize = PTHREAD_SIZE;
                guardsize = 0;
                pthreadoff = 0;
@@ -621,10 +631,32 @@ _pthread_allocate(const pthread_attr_t *attrs, void **stack)
        if (kr != KERN_SUCCESS) {
                kr = mach_vm_allocate(mach_task_self(), &allocaddr, allocsize,
                                 VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE);
        if (kr != KERN_SUCCESS) {
                kr = mach_vm_allocate(mach_task_self(), &allocaddr, allocsize,
                                 VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE);
+       } else if (__syscall_logger && !from_mach_thread) {
+               // libsyscall will not output malloc stack logging events when
+               // VM_MEMORY_STACK is passed in to facilitate mach thread promotion.
+               // To avoid losing the stack traces for normal p-thread create
+               // operations, libpthread must pretend to be the vm syscall and log
+               // the allocations. <rdar://36418708>
+               int eventTypeFlags = stack_logging_type_vm_allocate |
+                               stack_logging_type_mapped_file_or_shared_mem;
+               __syscall_logger(eventTypeFlags | VM_MAKE_TAG(VM_MEMORY_STACK),
+                               (uintptr_t)mach_task_self(), (uintptr_t)allocsize, 0,
+                               (uintptr_t)allocaddr, 0);
        }
        }
+
        if (kr != KERN_SUCCESS) {
                *stack  = NULL;
                return NULL;
        if (kr != KERN_SUCCESS) {
                *stack  = NULL;
                return NULL;
+       } else if (__syscall_logger && !from_mach_thread) {
+               // libsyscall will not output malloc stack logging events when
+               // VM_MEMORY_STACK is passed in to facilitate mach thread promotion.
+               // To avoid losing the stack traces for normal p-thread create
+               // operations, libpthread must pretend to be the vm syscall and log
+               // the allocations. <rdar://36418708>
+               int eventTypeFlags = stack_logging_type_vm_allocate;
+               __syscall_logger(eventTypeFlags | VM_MAKE_TAG(VM_MEMORY_STACK),
+                                                (uintptr_t)mach_task_self(), (uintptr_t)allocsize, 0,
+                                                (uintptr_t)allocaddr, 0);
        }
 
        // The stack grows down.
        }
 
        // The stack grows down.
@@ -662,7 +694,9 @@ _pthread_deallocate(pthread_t t, bool from_mach_thread)
                        _pthread_introspection_thread_destroy(t);
                }
                ret = mach_vm_deallocate(mach_task_self(), t->freeaddr, t->freesize);
                        _pthread_introspection_thread_destroy(t);
                }
                ret = mach_vm_deallocate(mach_task_self(), t->freeaddr, t->freesize);
-               PTHREAD_ASSERT(ret == KERN_SUCCESS);
+               if (ret != KERN_SUCCESS) {
+                       PTHREAD_INTERNAL_CRASH(ret, "Unable to deallocate stack");
+               }
        }
 }
 
        }
 }
 
@@ -700,8 +734,6 @@ PTHREAD_NORETURN PTHREAD_NOINLINE PTHREAD_NOT_TAIL_CALLED
 static void
 _pthread_terminate(pthread_t t, void *exit_value)
 {
 static void
 _pthread_terminate(pthread_t t, void *exit_value)
 {
-       PTHREAD_ASSERT(t == pthread_self());
-
        _pthread_introspection_thread_terminate(t);
 
        uintptr_t freeaddr = (uintptr_t)t->freeaddr;
        _pthread_introspection_thread_terminate(t);
 
        uintptr_t freeaddr = (uintptr_t)t->freeaddr;
@@ -839,38 +871,27 @@ _pthread_terminate_invoke(pthread_t t, void *exit_value)
 
 #pragma mark pthread start / body
 
 
 #pragma mark pthread start / body
 
-/*
- * Create and start execution of a new thread.
- */
-PTHREAD_NOINLINE PTHREAD_NORETURN
-static void
-_pthread_body(pthread_t self, bool needs_tsd_base_set)
-{
-       _pthread_set_self_internal(self, needs_tsd_base_set);
-       __pthread_started_thread(self);
-       _pthread_exit(self, (self->fun)(self->arg));
-}
-
 PTHREAD_NORETURN
 void
 _pthread_start(pthread_t self, mach_port_t kport,
                __unused void *(*fun)(void *), __unused void *arg,
                __unused size_t stacksize, unsigned int pflags)
 {
 PTHREAD_NORETURN
 void
 _pthread_start(pthread_t self, mach_port_t kport,
                __unused void *(*fun)(void *), __unused void *arg,
                __unused size_t stacksize, unsigned int pflags)
 {
-       bool thread_tsd_bsd_set = (bool)(pflags & PTHREAD_START_TSD_BASE_SET);
-
        if (os_unlikely(pflags & PTHREAD_START_SUSPENDED)) {
        if (os_unlikely(pflags & PTHREAD_START_SUSPENDED)) {
-               PTHREAD_INTERNAL_CRASH(0,
+               PTHREAD_INTERNAL_CRASH(pflags,
                                "kernel without PTHREAD_START_SUSPENDED support");
        }
                                "kernel without PTHREAD_START_SUSPENDED support");
        }
-#if DEBUG
-       PTHREAD_ASSERT(MACH_PORT_VALID(kport));
-       PTHREAD_ASSERT(_pthread_kernel_thread(self) == kport);
-#endif
-       // will mark the thread initialized
+       if (os_unlikely((pflags & PTHREAD_START_TSD_BASE_SET) == 0)) {
+               PTHREAD_INTERNAL_CRASH(pflags,
+                               "thread_set_tsd_base() wasn't called by the kernel");
+       }
+       PTHREAD_DEBUG_ASSERT(MACH_PORT_VALID(kport));
+       PTHREAD_DEBUG_ASSERT(_pthread_kernel_thread(self) == kport);
        _pthread_markcancel_if_canceled(self, kport);
 
        _pthread_markcancel_if_canceled(self, kport);
 
-       _pthread_body(self, !thread_tsd_bsd_set);
+       _pthread_set_self_internal(self);
+       __pthread_started_thread(self);
+       _pthread_exit(self, (self->fun)(self->arg));
 }
 
 PTHREAD_ALWAYS_INLINE
 }
 
 PTHREAD_ALWAYS_INLINE
@@ -878,9 +899,7 @@ static inline void
 _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs,
                void *stackaddr, size_t stacksize, void *freeaddr, size_t freesize)
 {
 _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs,
                void *stackaddr, size_t stacksize, void *freeaddr, size_t freesize)
 {
-#if DEBUG
-       PTHREAD_ASSERT(t->sig != _PTHREAD_SIG);
-#endif
+       PTHREAD_DEBUG_ASSERT(t->sig != _PTHREAD_SIG);
 
        t->sig = _PTHREAD_SIG;
        t->tsd[_PTHREAD_TSD_SLOT_PTHREAD_SELF] = t;
 
        t->sig = _PTHREAD_SIG;
        t->tsd[_PTHREAD_TSD_SLOT_PTHREAD_SELF] = t;
@@ -965,13 +984,12 @@ size_t
 pthread_get_stacksize_np(pthread_t t)
 {
        size_t size = 0;
 pthread_get_stacksize_np(pthread_t t)
 {
        size_t size = 0;
-       size_t stacksize = t->stackaddr - t->stackbottom;
 
        if (t == NULL) {
                return ESRCH; // XXX bug?
        }
 
 
        if (t == NULL) {
                return ESRCH; // XXX bug?
        }
 
-#if !defined(__arm__) && !defined(__arm64__)
+#if TARGET_OS_OSX
        // The default rlimit based allocations will be provided with a stacksize
        // of the current limit and a freesize of the max.  However, custom
        // allocations will just have the guard page to free.  If we aren't in the
        // The default rlimit based allocations will be provided with a stacksize
        // of the current limit and a freesize of the max.  However, custom
        // allocations will just have the guard page to free.  If we aren't in the
@@ -982,37 +1000,40 @@ pthread_get_stacksize_np(pthread_t t)
        //
        // Of course, on arm rlim_cur == rlim_max and there's only the one guard
        // page.  So, we can skip all this there.
        //
        // Of course, on arm rlim_cur == rlim_max and there's only the one guard
        // page.  So, we can skip all this there.
-       if (t == main_thread() && stacksize + vm_page_size != t->freesize) {
-               // We want to call getrlimit() just once, as it's relatively expensive
-               static size_t rlimit_stack;
+       if (t == main_thread()) {
+               size_t stacksize = t->stackaddr - t->stackbottom;
+
+               if (stacksize + vm_page_size != t->freesize) {
+                       // We want to call getrlimit() just once, as it's relatively
+                       // expensive
+                       static size_t rlimit_stack;
 
 
-               if (rlimit_stack == 0) {
-                       struct rlimit limit;
-                       int ret = getrlimit(RLIMIT_STACK, &limit);
+                       if (rlimit_stack == 0) {
+                               struct rlimit limit;
+                               int ret = getrlimit(RLIMIT_STACK, &limit);
 
 
-                       if (ret == 0) {
-                               rlimit_stack = (size_t) limit.rlim_cur;
+                               if (ret == 0) {
+                                       rlimit_stack = (size_t) limit.rlim_cur;
+                               }
                        }
                        }
-               }
 
 
-               if (rlimit_stack == 0 || rlimit_stack > t->freesize) {
-                       return stacksize;
-               } else {
-                       return rlimit_stack;
+                       if (rlimit_stack == 0 || rlimit_stack > t->freesize) {
+                               return stacksize;
+                       } else {
+                               return round_page(rlimit_stack);
+                       }
                }
        }
                }
        }
-#endif /* !defined(__arm__) && !defined(__arm64__) */
+#endif /* TARGET_OS_OSX */
 
        if (t == pthread_self() || t == main_thread()) {
 
        if (t == pthread_self() || t == main_thread()) {
-               size = stacksize;
+               size = t->stackaddr - t->stackbottom;;
                goto out;
        }
 
        if (_pthread_validate_thread_and_list_lock(t)) {
                goto out;
        }
 
        if (_pthread_validate_thread_and_list_lock(t)) {
-               size = stacksize;
+               size = t->stackaddr - t->stackbottom;;
                _PTHREAD_UNLOCK(_pthread_list_lock);
                _PTHREAD_UNLOCK(_pthread_list_lock);
-       } else {
-               size = ESRCH; // XXX bug?
        }
 
 out:
        }
 
 out:
@@ -1108,6 +1129,24 @@ pthread_main_np(void)
 }
 
 
 }
 
 
+static int
+_pthread_threadid_slow(pthread_t thread, uint64_t *thread_id)
+{
+       unsigned int info_count = THREAD_IDENTIFIER_INFO_COUNT;
+       mach_port_t thport = _pthread_kernel_thread(thread);
+       struct thread_identifier_info info;
+       kern_return_t kr;
+
+       kr = thread_info(thport, THREAD_IDENTIFIER_INFO,
+                       (thread_info_t)&info, &info_count);
+       if (kr == KERN_SUCCESS && info.thread_id) {
+               *thread_id = info.thread_id;
+               os_atomic_store(&thread->thread_id, info.thread_id, relaxed);
+               return 0;
+       }
+       return EINVAL;
+}
+
 /*
  * if we are passed in a pthread_t that is NULL, then we return the current
  * thread's thread_id. So folks don't have to call pthread_self, in addition to
 /*
  * if we are passed in a pthread_t that is NULL, then we return the current
  * thread's thread_id. So folks don't have to call pthread_self, in addition to
@@ -1129,10 +1168,11 @@ pthread_threadid_np(pthread_t thread, uint64_t *thread_id)
        } else if (!_pthread_validate_thread_and_list_lock(thread)) {
                res = ESRCH;
        } else {
        } else if (!_pthread_validate_thread_and_list_lock(thread)) {
                res = ESRCH;
        } else {
-               if (thread->thread_id == 0) {
-                       res = EINVAL;
-               } else {
-                       *thread_id = thread->thread_id;
+               *thread_id = os_atomic_load(&thread->thread_id, relaxed);
+               if (os_unlikely(*thread_id == 0)) {
+                       // there is a race at init because the thread sets its own TID.
+                       // correct this by asking mach
+                       res = _pthread_threadid_slow(thread, thread_id);
                }
                _PTHREAD_UNLOCK(_pthread_list_lock);
        }
                }
                _PTHREAD_UNLOCK(_pthread_list_lock);
        }
@@ -1235,7 +1275,7 @@ static inline void
 __pthread_started_thread(pthread_t t)
 {
        mach_port_t kport = _pthread_kernel_thread(t);
 __pthread_started_thread(pthread_t t)
 {
        mach_port_t kport = _pthread_kernel_thread(t);
-       if (os_slowpath(!MACH_PORT_VALID(kport))) {
+       if (os_unlikely(!MACH_PORT_VALID(kport))) {
                PTHREAD_CLIENT_CRASH(kport,
                                "Unable to allocate thread port, possible port leak");
        }
                PTHREAD_CLIENT_CRASH(kport,
                                "Unable to allocate thread port, possible port leak");
        }
@@ -1277,7 +1317,7 @@ _pthread_create(pthread_t *thread, const pthread_attr_t *attrs,
 
        __is_threaded = 1;
 
 
        __is_threaded = 1;
 
-       t =_pthread_allocate(attrs, &stack);
+       t =_pthread_allocate(attrs, &stack, from_mach_thread);
        if (t == NULL) {
                return EAGAIN;
        }
        if (t == NULL) {
                return EAGAIN;
        }
@@ -1297,10 +1337,6 @@ _pthread_create(pthread_t *thread, const pthread_attr_t *attrs,
                return EAGAIN;
        }
 
                return EAGAIN;
        }
 
-       if (create_flags & _PTHREAD_CREATE_SUSPENDED) {
-               _pthread_markcancel_if_canceled(t, _pthread_kernel_thread(t));
-       }
-
        // n.b. if a thread is created detached and exits, t will be invalid
        *thread = t;
        return 0;
        // n.b. if a thread is created detached and exits, t will be invalid
        *thread = t;
        return 0;
@@ -1322,70 +1358,10 @@ pthread_create_from_mach_thread(pthread_t *thread, const pthread_attr_t *attr,
        return _pthread_create(thread, attr, start_routine, arg, flags);
 }
 
        return _pthread_create(thread, attr, start_routine, arg, flags);
 }
 
-#if !defined(__OPEN_SOURCE__) && TARGET_OS_OSX // 40703288
-/* Functions defined in machine-dependent files. */
-PTHREAD_NOEXPORT void _pthread_setup_suspended(pthread_t th, void (*f)(pthread_t), void *sp);
-
-PTHREAD_NORETURN
-static void
-_pthread_suspended_body(pthread_t self)
-{
-       _pthread_set_self(self);
-       __pthread_started_thread(self);
-       _pthread_exit(self, (self->fun)(self->arg));
-}
-
-static int
-_pthread_create_suspended_np(pthread_t *thread, const pthread_attr_t *attrs,
-               void *(*start_routine)(void *), void *arg)
-{
-       pthread_t t;
-       void *stack;
-       mach_port_t kernel_thread = MACH_PORT_NULL;
-
-       if (attrs == NULL) {
-               attrs = &_pthread_attr_default;
-       } else if (attrs->sig != _PTHREAD_ATTR_SIG) {
-               return EINVAL;
-       }
-
-       t = _pthread_allocate(attrs, &stack);
-       if (t == NULL) {
-               return EAGAIN;
-       }
-
-       if (thread_create(mach_task_self(), &kernel_thread) != KERN_SUCCESS) {
-               _pthread_deallocate(t, false);
-               return EAGAIN;
-       }
-
-       _pthread_set_kernel_thread(t, kernel_thread);
-       (void)pthread_setschedparam_internal(t, kernel_thread,
-                       t->tl_policy, &t->tl_param);
-
-       __is_threaded = 1;
-
-       t->arg = arg;
-       t->fun = start_routine;
-       t->cancel_state |= _PTHREAD_CANCEL_INITIALIZED;
-       __pthread_add_thread(t, false);
-
-       // Set up a suspended thread.
-       _pthread_setup_suspended(t, _pthread_suspended_body, stack);
-       *thread = t;
-       return 0;
-}
-#endif // !defined(__OPEN_SOURCE__) && TARGET_OS_OSX
-
 int
 pthread_create_suspended_np(pthread_t *thread, const pthread_attr_t *attr,
                void *(*start_routine)(void *), void *arg)
 {
 int
 pthread_create_suspended_np(pthread_t *thread, const pthread_attr_t *attr,
                void *(*start_routine)(void *), void *arg)
 {
-#if !defined(__OPEN_SOURCE__) && TARGET_OS_OSX // 40703288
-       if (_os_xbs_chrooted) {
-               return _pthread_create_suspended_np(thread, attr, start_routine, arg);
-       }
-#endif
        unsigned int flags = _PTHREAD_CREATE_SUSPENDED;
        return _pthread_create(thread, attr, start_routine, arg, flags);
 }
        unsigned int flags = _PTHREAD_CREATE_SUSPENDED;
        return _pthread_create(thread, attr, start_routine, arg, flags);
 }
@@ -1433,13 +1409,10 @@ pthread_kill(pthread_t th, int sig)
        }
 
        mach_port_t kport = MACH_PORT_NULL;
        }
 
        mach_port_t kport = MACH_PORT_NULL;
-       if (!_pthread_is_valid(th, &kport)) {
-               return ESRCH; // Not a valid thread.
-       }
-
-       // Don't signal workqueue threads.
-       if (th->wqthread != 0 && th->wqkillset == 0) {
-               return ENOTSUP;
+       {
+               if (!_pthread_is_valid(th, &kport)) {
+                       return ESRCH;
+               }
        }
 
        int ret = __pthread_kill(kport, sig);
        }
 
        int ret = __pthread_kill(kport, sig);
@@ -1454,13 +1427,9 @@ PTHREAD_NOEXPORT_VARIANT
 int
 __pthread_workqueue_setkill(int enable)
 {
 int
 __pthread_workqueue_setkill(int enable)
 {
-       pthread_t self = pthread_self();
-
-       _PTHREAD_LOCK(self->lock);
-       self->wqkillset = enable ? 1 : 0;
-       _PTHREAD_UNLOCK(self->lock);
-
-       return 0;
+       {
+               return __bsdthread_ctl(BSDTHREAD_CTL_WORKQ_ALLOW_KILL, enable, 0, 0);
+       }
 }
 
 
 }
 
 
@@ -1629,7 +1598,8 @@ _pthread_set_self(pthread_t p)
                return _pthread_set_self_dyld();
        }
 #endif // VARIANT_DYLD
                return _pthread_set_self_dyld();
        }
 #endif // VARIANT_DYLD
-       _pthread_set_self_internal(p, true);
+       _pthread_set_self_internal(p);
+       _thread_set_tsd_base(&p->tsd[0]);
 }
 
 #if VARIANT_DYLD
 }
 
 #if VARIANT_DYLD
@@ -1660,17 +1630,13 @@ _pthread_set_self_dyld(void)
 
 PTHREAD_ALWAYS_INLINE
 static inline void
 
 PTHREAD_ALWAYS_INLINE
 static inline void
-_pthread_set_self_internal(pthread_t p, bool needs_tsd_base_set)
+_pthread_set_self_internal(pthread_t p)
 {
 {
-       p->thread_id = __thread_selfid();
+       os_atomic_store(&p->thread_id, __thread_selfid(), relaxed);
 
        if (os_unlikely(p->thread_id == -1ull)) {
                PTHREAD_INTERNAL_CRASH(0, "failed to set thread_id");
        }
 
        if (os_unlikely(p->thread_id == -1ull)) {
                PTHREAD_INTERNAL_CRASH(0, "failed to set thread_id");
        }
-
-       if (needs_tsd_base_set) {
-               _thread_set_tsd_base(&p->tsd[0]);
-       }
 }
 
 
 }
 
 
@@ -1899,10 +1865,12 @@ __pthread_init(const struct _libpthread_functions *pthread_funcs,
        // and make it our main thread point.
        pthread_t thread = (pthread_t)_pthread_getspecific_direct(
                        _PTHREAD_TSD_SLOT_PTHREAD_SELF);
        // and make it our main thread point.
        pthread_t thread = (pthread_t)_pthread_getspecific_direct(
                        _PTHREAD_TSD_SLOT_PTHREAD_SELF);
-       PTHREAD_ASSERT(thread);
+       if (os_unlikely(thread == NULL)) {
+               PTHREAD_INTERNAL_CRASH(0, "PTHREAD_SELF TSD not initialized");
+       }
        _main_thread_ptr = thread;
 
        _main_thread_ptr = thread;
 
-       PTHREAD_ASSERT(_pthread_attr_default.qosclass ==
+       PTHREAD_DEBUG_ASSERT(_pthread_attr_default.qosclass ==
                        _pthread_default_priority(0));
        _pthread_struct_init(thread, &_pthread_attr_default,
                        stackaddr, stacksize, allocaddr, allocsize);
                        _pthread_default_priority(0));
        _pthread_struct_init(thread, &_pthread_attr_default,
                        stackaddr, stacksize, allocaddr, allocsize);
@@ -1950,7 +1918,6 @@ _pthread_main_thread_init(pthread_t p)
        p->tl_exit_gate = MACH_PORT_NULL;
        p->tsd[__TSD_SEMAPHORE_CACHE] = (void*)(uintptr_t)SEMAPHORE_NULL;
        p->tsd[__TSD_MACH_SPECIAL_REPLY] = 0;
        p->tl_exit_gate = MACH_PORT_NULL;
        p->tsd[__TSD_SEMAPHORE_CACHE] = (void*)(uintptr_t)SEMAPHORE_NULL;
        p->tsd[__TSD_MACH_SPECIAL_REPLY] = 0;
-       p->cancel_state |= _PTHREAD_CANCEL_INITIALIZED;
 
        // Initialize the list of threads with the new main thread.
        TAILQ_INSERT_HEAD(&__pthread_head, p, tl_plist);
 
        // Initialize the list of threads with the new main thread.
        TAILQ_INSERT_HEAD(&__pthread_head, p, tl_plist);
@@ -1964,7 +1931,7 @@ void
 _pthread_main_thread_postfork_init(pthread_t p)
 {
        _pthread_main_thread_init(p);
 _pthread_main_thread_postfork_init(pthread_t p)
 {
        _pthread_main_thread_init(p);
-       _pthread_set_self_internal(p, false);
+       _pthread_set_self_internal(p);
 }
 
 int
 }
 
 int
@@ -1987,6 +1954,25 @@ pthread_yield_np(void)
        sched_yield();
 }
 
        sched_yield();
 }
 
+// Libsystem knows about this symbol and exports it to libsyscall
+int
+pthread_current_stack_contains_np(const void *addr, size_t length)
+{
+       uintptr_t begin = (uintptr_t) addr, end;
+       uintptr_t stack_base = (uintptr_t) _pthread_self_direct()->stackbottom;
+       uintptr_t stack_top = (uintptr_t) _pthread_self_direct()->stackaddr;
+
+       if (stack_base == stack_top) {
+               return -ENOTSUP;
+       }
+
+       if (__builtin_add_overflow(begin, length, &end)) {
+               return -EINVAL;
+       }
+
+       return stack_base <= begin && end <= stack_top;
+}
+
 
 
 // Libsystem knows about this symbol and exports it to libsyscall
 
 
 // Libsystem knows about this symbol and exports it to libsyscall
@@ -2021,7 +2007,15 @@ _pthread_clear_qos_tsd(mach_port_t thread_port)
 
 
 #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__)
 
 
 #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__)
+#if __ARM64_ARCH_8_32__
+/*
+ * arm64_32 uses 64-bit sizes for the frame pointer and
+ * return address of a stack frame.
+ */
+typedef uint64_t frame_data_addr_t;
+#else
 typedef uintptr_t frame_data_addr_t;
 typedef uintptr_t frame_data_addr_t;
+#endif
 
 struct frame_data {
        frame_data_addr_t frame_addr_next;
 
 struct frame_data {
        frame_data_addr_t frame_addr_next;
@@ -2037,9 +2031,18 @@ pthread_stack_frame_decode_np(uintptr_t frame_addr, uintptr_t *return_addr)
        struct frame_data *frame = (struct frame_data *)frame_addr;
 
        if (return_addr) {
        struct frame_data *frame = (struct frame_data *)frame_addr;
 
        if (return_addr) {
+#if __has_feature(ptrauth_calls)
+               *return_addr = (uintptr_t)ptrauth_strip((void *)frame->ret_addr,
+                               ptrauth_key_return_address);
+#else
                *return_addr = (uintptr_t)frame->ret_addr;
                *return_addr = (uintptr_t)frame->ret_addr;
+#endif /* __has_feature(ptrauth_calls) */
        }
 
        }
 
+#if __has_feature(ptrauth_calls)
+       return (uintptr_t)ptrauth_strip((void *)frame->frame_addr_next,
+                       ptrauth_key_frame_pointer);
+#endif /* __has_feature(ptrauth_calls) */
        return (uintptr_t)frame->frame_addr_next;
 }
 
        return (uintptr_t)frame->frame_addr_next;
 }
 
@@ -2175,11 +2178,13 @@ _pthread_wqthread_setup(pthread_t self, mach_port_t kport, void *stacklowaddr,
        self->wqthread = 1;
        self->wqkillset = 0;
        self->tl_joinable = false;
        self->wqthread = 1;
        self->wqkillset = 0;
        self->tl_joinable = false;
-       self->cancel_state |= _PTHREAD_CANCEL_INITIALIZED;
 
        // Update the running thread count and set childrun bit.
 
        // Update the running thread count and set childrun bit.
-       bool thread_tsd_base_set = (bool)(flags & WQ_FLAG_THREAD_TSD_BASE_SET);
-       _pthread_set_self_internal(self, !thread_tsd_base_set);
+       if (os_unlikely((flags & WQ_FLAG_THREAD_TSD_BASE_SET) == 0)) {
+               PTHREAD_INTERNAL_CRASH(flags,
+                               "thread_set_tsd_base() wasn't called by the kernel");
+       }
+       _pthread_set_self_internal(self);
        __pthread_add_thread(self, false);
        __pthread_started_thread(self);
 }
        __pthread_add_thread(self, false);
        __pthread_started_thread(self);
 }
@@ -2212,36 +2217,36 @@ _pthread_wqthread(pthread_t self, mach_port_t kport, void *stacklowaddr,
        }
 
        pthread_priority_t pp;
        }
 
        pthread_priority_t pp;
+
        if (flags & WQ_FLAG_THREAD_OUTSIDEQOS) {
        if (flags & WQ_FLAG_THREAD_OUTSIDEQOS) {
-               self->wqoutsideqos = 1;
+               self->wq_outsideqos = 1;
                pp = _pthread_priority_make_from_thread_qos(THREAD_QOS_LEGACY, 0,
                                _PTHREAD_PRIORITY_FALLBACK_FLAG);
        } else {
                pp = _pthread_priority_make_from_thread_qos(THREAD_QOS_LEGACY, 0,
                                _PTHREAD_PRIORITY_FALLBACK_FLAG);
        } else {
-               self->wqoutsideqos = 0;
+               self->wq_outsideqos = 0;
                pp = _pthread_wqthread_priority(flags);
        }
 
        self->tsd[_PTHREAD_TSD_SLOT_PTHREAD_QOS_CLASS] = (void *)pp;
 
        // avoid spills on the stack hard to keep used stack space minimal
                pp = _pthread_wqthread_priority(flags);
        }
 
        self->tsd[_PTHREAD_TSD_SLOT_PTHREAD_QOS_CLASS] = (void *)pp;
 
        // avoid spills on the stack hard to keep used stack space minimal
-       if (nkevents == WORKQ_EXIT_THREAD_NKEVENT) {
-               goto exit;
+       if (os_unlikely(nkevents == WORKQ_EXIT_THREAD_NKEVENT)) {
+               _pthread_wqthread_exit(self);
        } else if (flags & WQ_FLAG_THREAD_WORKLOOP) {
        } else if (flags & WQ_FLAG_THREAD_WORKLOOP) {
+               kqueue_id_t *kqidptr = (kqueue_id_t *)keventlist - 1;
                self->fun = (void *(*)(void*))__libdispatch_workloopfunction;
                self->fun = (void *(*)(void*))__libdispatch_workloopfunction;
-               self->wq_retop = WQOPS_THREAD_WORKLOOP_RETURN;
-               self->wq_kqid_ptr = ((kqueue_id_t *)keventlist - 1);
                self->arg = keventlist;
                self->wq_nevents = nkevents;
                self->arg = keventlist;
                self->wq_nevents = nkevents;
+               (*__libdispatch_workloopfunction)(kqidptr, &self->arg, &self->wq_nevents);
+               __workq_kernreturn(WQOPS_THREAD_WORKLOOP_RETURN, self->arg, self->wq_nevents, 0);
        } else if (flags & WQ_FLAG_THREAD_KEVENT) {
                self->fun = (void *(*)(void*))__libdispatch_keventfunction;
        } else if (flags & WQ_FLAG_THREAD_KEVENT) {
                self->fun = (void *(*)(void*))__libdispatch_keventfunction;
-               self->wq_retop = WQOPS_THREAD_KEVENT_RETURN;
-               self->wq_kqid_ptr = NULL;
                self->arg = keventlist;
                self->wq_nevents = nkevents;
                self->arg = keventlist;
                self->wq_nevents = nkevents;
+               (*__libdispatch_keventfunction)(&self->arg, &self->wq_nevents);
+               __workq_kernreturn(WQOPS_THREAD_KEVENT_RETURN, self->arg, self->wq_nevents, 0);
        } else {
                self->fun = (void *(*)(void*))__libdispatch_workerfunction;
        } else {
                self->fun = (void *(*)(void*))__libdispatch_workerfunction;
-               self->wq_retop = WQOPS_THREAD_RETURN;
-               self->wq_kqid_ptr = NULL;
                self->arg = (void *)(uintptr_t)pp;
                self->wq_nevents = 0;
                if (os_likely(__workq_newapi)) {
                self->arg = (void *)(uintptr_t)pp;
                self->wq_nevents = 0;
                if (os_likely(__workq_newapi)) {
@@ -2249,33 +2254,15 @@ _pthread_wqthread(pthread_t self, mach_port_t kport, void *stacklowaddr,
                } else {
                        _pthread_wqthread_legacy_worker_wrap(pp);
                }
                } else {
                        _pthread_wqthread_legacy_worker_wrap(pp);
                }
-               goto just_return;
-       }
-
-       if (nkevents > 0) {
-kevent_errors_retry:
-               if (self->wq_retop == WQOPS_THREAD_WORKLOOP_RETURN) {
-                       ((pthread_workqueue_function_workloop_t)self->fun)
-                                       (self->wq_kqid_ptr, &self->arg, &self->wq_nevents);
-               } else {
-                       ((pthread_workqueue_function_kevent_t)self->fun)
-                                       (&self->arg, &self->wq_nevents);
-               }
-               int rc = __workq_kernreturn(self->wq_retop, self->arg, self->wq_nevents, 0);
-               if (os_unlikely(rc > 0)) {
-                       self->wq_nevents = rc;
-                       goto kevent_errors_retry;
-               }
-               if (os_unlikely(rc < 0)) {
-                       PTHREAD_INTERNAL_CRASH(self->err_no, "kevent (workloop) failed");
-               }
-       } else {
-just_return:
-               __workq_kernreturn(self->wq_retop, NULL, 0, 0);
+               __workq_kernreturn(WQOPS_THREAD_RETURN, NULL, 0, 0);
        }
 
        }
 
-exit:
-       _pthread_wqthread_exit(self);
+       _os_set_crash_log_cause_and_message(self->err_no,
+                       "BUG IN LIBPTHREAD: __workq_kernreturn returned");
+       /*
+        * 52858993: we should never return but the compiler insists on outlining,
+        * so the __builtin_trap() is in _start_wqthread in pthread_asm.s
+        */
 }
 
 
 }
 
 
@@ -2288,33 +2275,70 @@ _Static_assert(WORKQ_KEVENT_EVENT_BUFFER_LEN == WQ_KEVENT_LIST_LEN,
 void
 pthread_workqueue_setdispatchoffset_np(int offset)
 {
 void
 pthread_workqueue_setdispatchoffset_np(int offset)
 {
-       __libdispatch_offset = offset;
+       __workq_kernreturn(WQOPS_QUEUE_NEWSPISUPP, NULL, offset, 0x00);
 }
 
 }
 
-static int
-pthread_workqueue_setdispatch_with_workloop_np(pthread_workqueue_function2_t queue_func,
-               pthread_workqueue_function_kevent_t kevent_func,
-               pthread_workqueue_function_workloop_t workloop_func)
+int
+pthread_workqueue_setup(struct pthread_workqueue_config *cfg, size_t cfg_size)
 {
 {
-       int res = EBUSY;
+       int rv = EBUSY;
+       struct workq_dispatch_config wdc_cfg;
+       size_t min_size = 0;
+
+       if (cfg_size < sizeof(uint32_t)) {
+               return EINVAL;
+       }
+
+       switch (cfg->version) {
+               case 1:
+                       min_size = offsetof(struct pthread_workqueue_config, queue_label_offs);
+                       break;
+               case 2:
+                       min_size = sizeof(struct pthread_workqueue_config);
+                       break;
+               default:
+                       return EINVAL;
+               }
+
+       if (!cfg || cfg_size < min_size) {
+               return EINVAL;
+       }
+
+       if (cfg->flags & ~PTHREAD_WORKQUEUE_CONFIG_SUPPORTED_FLAGS ||
+               cfg->version < PTHREAD_WORKQUEUE_CONFIG_MIN_SUPPORTED_VERSION) {
+               return ENOTSUP;
+       }
+
        if (__libdispatch_workerfunction == NULL) {
        if (__libdispatch_workerfunction == NULL) {
-               // Check whether the kernel supports new SPIs
-               res = __workq_kernreturn(WQOPS_QUEUE_NEWSPISUPP, NULL, __libdispatch_offset, kevent_func != NULL ? 0x01 : 0x00);
-               if (res == -1){
-                       res = ENOTSUP;
+               __workq_newapi = true;
+
+               wdc_cfg.wdc_version = WORKQ_DISPATCH_CONFIG_VERSION;
+               wdc_cfg.wdc_flags = 0;
+               wdc_cfg.wdc_queue_serialno_offs = cfg->queue_serialno_offs;
+#if WORKQ_DISPATCH_CONFIG_VERSION >= 2
+               wdc_cfg.wdc_queue_label_offs = cfg->queue_label_offs;
+#endif
+
+               // Tell the kernel about dispatch internals
+               rv = (int) __workq_kernreturn(WQOPS_SETUP_DISPATCH, &wdc_cfg, sizeof(wdc_cfg), 0);
+               if (rv == -1) {
+                       return errno;
                } else {
                } else {
-                       __libdispatch_workerfunction = queue_func;
-                       __libdispatch_keventfunction = kevent_func;
-                       __libdispatch_workloopfunction = workloop_func;
+                       __libdispatch_keventfunction = cfg->kevent_cb;
+                       __libdispatch_workloopfunction = cfg->workloop_cb;
+                       __libdispatch_workerfunction = cfg->workq_cb;
 
                        // Prepare the kernel for workq action
                        (void)__workq_open();
                        if (__is_threaded == 0) {
                                __is_threaded = 1;
                        }
 
                        // Prepare the kernel for workq action
                        (void)__workq_open();
                        if (__is_threaded == 0) {
                                __is_threaded = 1;
                        }
+
+                       return 0;
                }
        }
                }
        }
-       return res;
+
+       return rv;
 }
 
 int
 }
 
 int
@@ -2323,15 +2347,17 @@ _pthread_workqueue_init_with_workloop(pthread_workqueue_function2_t queue_func,
                pthread_workqueue_function_workloop_t workloop_func,
                int offset, int flags)
 {
                pthread_workqueue_function_workloop_t workloop_func,
                int offset, int flags)
 {
-       if (flags != 0) {
-               return ENOTSUP;
-       }
-
-       __workq_newapi = true;
-       __libdispatch_offset = offset;
+       struct pthread_workqueue_config cfg = {
+               .version = PTHREAD_WORKQUEUE_CONFIG_VERSION,
+               .flags = 0,
+               .workq_cb = queue_func,
+               .kevent_cb = kevent_func,
+               .workloop_cb = workloop_func,
+               .queue_serialno_offs = offset,
+               .queue_label_offs = 0,
+       };
 
 
-       int rv = pthread_workqueue_setdispatch_with_workloop_np(queue_func, kevent_func, workloop_func);
-       return rv;
+       return pthread_workqueue_setup(&cfg, sizeof(cfg));
 }
 
 int
 }
 
 int
@@ -2351,7 +2377,17 @@ _pthread_workqueue_init(pthread_workqueue_function2_t func, int offset, int flag
 int
 pthread_workqueue_setdispatch_np(pthread_workqueue_function_t worker_func)
 {
 int
 pthread_workqueue_setdispatch_np(pthread_workqueue_function_t worker_func)
 {
-       return pthread_workqueue_setdispatch_with_workloop_np((pthread_workqueue_function2_t)worker_func, NULL, NULL);
+       struct pthread_workqueue_config cfg = {
+               .version = PTHREAD_WORKQUEUE_CONFIG_VERSION,
+               .flags = 0,
+               .workq_cb = (uint64_t)(pthread_workqueue_function2_t)worker_func,
+               .kevent_cb = 0,
+               .workloop_cb = 0,
+               .queue_serialno_offs = 0,
+               .queue_label_offs = 0,
+       };
+
+       return pthread_workqueue_setup(&cfg, sizeof(cfg));
 }
 
 int
 }
 
 int
@@ -2589,6 +2625,8 @@ _pthread_introspection_thread_destroy(pthread_t t)
        _pthread_introspection_hook_callout_thread_destroy(t);
 }
 
        _pthread_introspection_hook_callout_thread_destroy(t);
 }
 
+
+#if !VARIANT_DYLD
 #pragma mark libplatform shims
 
 #include <platform/string.h>
 #pragma mark libplatform shims
 
 #include <platform/string.h>
@@ -2623,3 +2661,4 @@ memcpy(void* a, const void* b, unsigned long s)
        return _platform_memmove(a, b, s);
 }
 
        return _platform_memmove(a, b, s);
 }
 
+#endif // !VARIANT_DYLD
index 90afe461bfec6a8168ae7a1c616940160d91f9d8..244957a86209a8deca3904c593bfb2f97e9c5144 100644 (file)
        .globl _start_wqthread
 _start_wqthread:
        // This routine is never called directly by user code, jumped from kernel
        .globl _start_wqthread
 _start_wqthread:
        // This routine is never called directly by user code, jumped from kernel
+       // Push a sentinel frame, so backtracers know when to stop.
+       push   $0
        push   %rbp
        mov    %rsp,%rbp
        push   %rbp
        mov    %rsp,%rbp
-       sub    $24,%rsp         // align the stack
+       sub    $16,%rsp      // align the stack
        call   __pthread_wqthread
        call   __pthread_wqthread
-       leave
-       ret
+       ud2 // never returns
 
        .align 2, 0x90
        .globl _thread_start
 _thread_start:
        // This routine is never called directly by user code, jumped from kernel
 
        .align 2, 0x90
        .globl _thread_start
 _thread_start:
        // This routine is never called directly by user code, jumped from kernel
+       // Push a sentinel frame, so backtracers know when to stop.
+       push   $0
        push   %rbp
        mov    %rsp,%rbp
        push   %rbp
        mov    %rsp,%rbp
-       sub    $24,%rsp         // align the stack
+       sub    $16,%rsp         // align the stack
        call   __pthread_start
        leave
        ret
        call   __pthread_start
        leave
        ret
@@ -74,6 +77,14 @@ ____chkstk_darwin: // %rax == alloca size
        popq   %rcx
        retq
 
        popq   %rcx
        retq
 
+Lcrash:
+       // POSIX mandates that stack overflow crashes with SIGSEGV
+       // so load an address in the guard page and dereference it
+       movq   %gs:_PTHREAD_STRUCT_DIRECT_STACKBOTTOM_OFFSET, %rcx
+       testq  %rcx, -8(%rcx)
+       // if main_thread caused stack growth with setrlimit()
+       // fall into Lprobe and eventually cause SIGSEGV.
+
 Lprobe:
        // probe the stack when it's not ours (altstack or some shenanigan)
        cmpq   $0x1000, %rax
 Lprobe:
        // probe the stack when it's not ours (altstack or some shenanigan)
        cmpq   $0x1000, %rax
@@ -93,9 +104,6 @@ Lend:
        popq   %rcx
        retq
 
        popq   %rcx
        retq
 
-Lcrash:
-       ud2
-
 #endif
 
 #elif defined(__i386__)
 #endif
 
 #elif defined(__i386__)
@@ -108,9 +116,11 @@ Lcrash:
        .globl _start_wqthread
 _start_wqthread:
        // This routine is never called directly by user code, jumped from kernel
        .globl _start_wqthread
 _start_wqthread:
        // This routine is never called directly by user code, jumped from kernel
+       // Push a sentinel frame, so backtracers know when to stop.
+       push   $0
        push   %ebp
        mov    %esp,%ebp
        push   %ebp
        mov    %esp,%ebp
-       sub    $28,%esp         // align the stack
+       sub    $24,%esp         // align the stack
        mov    %esi,20(%esp)    //arg5
        mov    %edi,16(%esp)    //arg5
        mov    %edx,12(%esp)    //arg4
        mov    %esi,20(%esp)    //arg5
        mov    %edi,16(%esp)    //arg5
        mov    %edx,12(%esp)    //arg4
@@ -118,16 +128,17 @@ _start_wqthread:
        mov    %ebx,4(%esp)             //arg2
        mov    %eax,(%esp)              //arg1
        call   __pthread_wqthread
        mov    %ebx,4(%esp)             //arg2
        mov    %eax,(%esp)              //arg1
        call   __pthread_wqthread
-       leave
-       ret
+       ud2 // never returns
 
        .align 2, 0x90
        .globl _thread_start
 _thread_start:
        // This routine is never called directly by user code, jumped from kernel
 
        .align 2, 0x90
        .globl _thread_start
 _thread_start:
        // This routine is never called directly by user code, jumped from kernel
+       // Push a sentinel frame, so backtracers know when to stop.
+       push   $0
        push   %ebp
        mov    %esp,%ebp
        push   %ebp
        mov    %esp,%ebp
-       sub    $28,%esp         // align the stack
+       sub    $24,%esp         // align the stack
        mov    %esi,20(%esp)    //arg6
        mov    %edi,16(%esp)    //arg5
        mov    %edx,12(%esp)    //arg4
        mov    %esi,20(%esp)    //arg6
        mov    %edi,16(%esp)    //arg5
        mov    %edx,12(%esp)    //arg4
@@ -165,6 +176,15 @@ ____chkstk_darwin: // %eax == alloca size
        popl   %ecx
        retl
 
        popl   %ecx
        retl
 
+Lcrash:
+       // POSIX mandates that stack overflow crashes with SIGSEGV
+       // so load an address in the guard page and dereference it
+       movl   %gs:0x0, %ecx    // pthread_self()
+       movl   _PTHREAD_STRUCT_DIRECT_STACKBOTTOM_OFFSET(%ecx), %ecx
+       testl  %ecx, -4(%ecx)
+       // if main_thread caused stack growth with setrlimit()
+       // fall into Lprobe and eventually cause SIGSEGV.
+
 Lprobe:
        // probe the stack when it's not ours (altstack or some shenanigan)
        cmpl   $0x1000, %eax
 Lprobe:
        // probe the stack when it's not ours (altstack or some shenanigan)
        cmpl   $0x1000, %eax
@@ -185,9 +205,6 @@ Lend:
        popl   %ecx
        retl
 
        popl   %ecx
        retl
 
-Lcrash:
-       ud2
-
 #endif
 
 #elif defined(__arm__)
 #endif
 
 #elif defined(__arm__)
@@ -206,30 +223,122 @@ Lcrash:
        .align 2
        .globl _start_wqthread
 _start_wqthread:
        .align 2
        .globl _start_wqthread
 _start_wqthread:
-#if __ARM_ARCH_7K__
-       /* align stack to 16 bytes before calling C */
-       sub sp, sp, #8
-#endif
+// Push a sentinel frame, so backtracers know when to stop.
+       mov ip, #0
+       str ip, [sp, #-4]!
+       str ip, [sp, #-4]!
        stmfd sp!, {r4, r5}
        bl __pthread_wqthread
        stmfd sp!, {r4, r5}
        bl __pthread_wqthread
+       trap // never returns
+
+       .text
+       .align 2
+       .globl _thread_start
+_thread_start:
+// Push a sentinel frame, so backtracers know when to stop.
+       mov ip, #0
+       str ip, [sp, #-4]!
+       str ip, [sp, #-4]!
+       stmfd sp!, {r4, r5}
+       bl __pthread_start
 // Stackshots will show the routine that happens to link immediately following
 // _start_wqthread.  So we add an extra instruction (nop) to make stackshots
 // more readable.
        nop
 
 // Stackshots will show the routine that happens to link immediately following
 // _start_wqthread.  So we add an extra instruction (nop) to make stackshots
 // more readable.
        nop
 
+#endif
+
+#elif defined(__arm64__)
+
+#include <mach/arm/syscall_sw.h>
+
+#ifndef VARIANT_DYLD
+
+// This routine is never called directly by user code, jumped from kernel
+// args 0 to 5 in registers.
+       .text
+       .align 2
+       .globl _start_wqthread
+_start_wqthread:
+// Push a sentinel frame, so backtracers know when to stop.
+       stp xzr, xzr, [sp, #-16]!
+       bl __pthread_wqthread
+       brk #1 // never returns
+
        .text
        .align 2
        .globl _thread_start
 _thread_start:
        .text
        .align 2
        .globl _thread_start
 _thread_start:
-#if __ARM_ARCH_7K__
-       /* align stack to 16 bytes before calling C */
-       sub sp, sp, #8
-#endif
-       stmfd sp!, {r4, r5}
+// Push a sentinel frame, so backtracers know when to stop.
+       stp xzr, xzr, [sp, #-16]!
        bl __pthread_start
        bl __pthread_start
-// See above
        nop
 
        nop
 
+       .text
+       .align 2
+       .globl _thread_chkstk_darwin
+_thread_chkstk_darwin:
+       .globl ____chkstk_darwin
+____chkstk_darwin: // %w9 == alloca size
+       stp     x10, x11, [sp, #-16]
+
+       // validate that the frame pointer is on our stack (no alt stack)
+       mrs     x10, TPIDRRO_EL0
+       and     x10, x10, #0xfffffffffffffff8
+
+       // (%sp - pthread_self()->stackaddr) > 0 ?
+#if defined(__ARM64_ARCH_8_32__)
+       ldur    w11, [x10, _PTHREAD_STRUCT_DIRECT_STACKADDR_OFFSET]
+#else
+       ldur    x11, [x10, _PTHREAD_STRUCT_DIRECT_STACKADDR_OFFSET]
+#endif
+       subs    x11, sp, x11
+       b.hs    Lprobe
+
+       // %sp <= pthread_self()->stackbottom ?
+#if defined(__ARM64_ARCH_8_32__)
+       ldur    w11, [x10, _PTHREAD_STRUCT_DIRECT_STACKBOTTOM_OFFSET]
+#else
+       ldur    x11, [x10, _PTHREAD_STRUCT_DIRECT_STACKBOTTOM_OFFSET]
+#endif
+       mov     x10, sp
+       cmp     x10, x11
+       b.ls    Lprobe
+
+       // %sp - (uintptr_t)%w9 < pthread_self()->stackbottom ?
+       subs    x10, x10, w9, uxtw
+       b.lo    Lcrash
+       cmp     x10, x11
+       b.lo    Lcrash
+
+Lexit:
+       ldp     x10, x11, [sp, #-16]
+       ret
+
+Lcrash:
+       // POSIX mandates that stack overflow crashes with SIGSEGV
+       // so load an address in the guard page and dereference it
+       //
+       // x11 contains pthread_self()->stackbottom already
+       ldr     x11, [x11, #-8]
+       // if main_thread caused stack growth with setrlimit()
+       // fall into Lprobe and eventually cause SIGSEGV.
+
+Lprobe:
+       mov     x10, sp
+       cmp     w9, #0x1000
+       b.lo    Lend
+Lloop:
+       sub     x10, x10, #0x1000
+       ldr     x11, [x10]
+       sub     w9, w9, #0x1000
+       cmp     w9, #0x1000
+       b.hi    Lloop
+Lend:
+       sub     x10, x10, x9
+       ldr     x11, [x10]
+       b       Lexit
+
 #endif
 
 #else
 #endif
 
 #else
index 8bb9c08a7c3e1aa1a418c1c649a85cb046a02e96..3df57a7953cab52c7704b02f6c6e58baa3d6fc29 100644 (file)
@@ -191,8 +191,7 @@ void
 _pthread_markcancel_if_canceled(pthread_t thread, mach_port_t kport)
 {
        const int flags = (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING);
 _pthread_markcancel_if_canceled(pthread_t thread, mach_port_t kport)
 {
        const int flags = (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING);
-       int state = os_atomic_or2o(thread, cancel_state,
-                       _PTHREAD_CANCEL_INITIALIZED, relaxed);
+       int state = os_atomic_load2o(thread, cancel_state, relaxed);
        if ((state & flags) == flags && __unix_conforming) {
                __pthread_markcancel(kport);
        }
        if ((state & flags) == flags && __unix_conforming) {
                __pthread_markcancel(kport);
        }
@@ -353,9 +352,7 @@ _pthread_joiner_abort_wait(pthread_t thread, pthread_join_context_t ctx)
                 * _pthread_joiner_prepost_wake() didn't happen
                 * allow another thread to join
                 */
                 * _pthread_joiner_prepost_wake() didn't happen
                 * allow another thread to join
                 */
-#if DEBUG
-               PTHREAD_ASSERT(thread->tl_join_ctx == ctx);
-#endif
+               PTHREAD_DEBUG_ASSERT(thread->tl_join_ctx == ctx);
                thread->tl_join_ctx = NULL;
                thread->tl_exit_gate = MACH_PORT_NULL;
                aborted = true;
                thread->tl_join_ctx = NULL;
                thread->tl_exit_gate = MACH_PORT_NULL;
                aborted = true;
@@ -422,9 +419,7 @@ _pthread_joiner_wait(pthread_t thread, pthread_join_context_t ctx, int conformin
        // If pthread_detach() was called, we can't safely dereference the thread,
        // else, decide who gets to deallocate the thread (see _pthread_terminate).
        if (!ctx->detached) {
        // If pthread_detach() was called, we can't safely dereference the thread,
        // else, decide who gets to deallocate the thread (see _pthread_terminate).
        if (!ctx->detached) {
-#if DEBUG
-               PTHREAD_ASSERT(thread->tl_join_ctx == ctx);
-#endif
+               PTHREAD_DEBUG_ASSERT(thread->tl_join_ctx == ctx);
                thread->tl_join_ctx = NULL;
                cleanup = thread->tl_joiner_cleans_up;
        }
                thread->tl_join_ctx = NULL;
                cleanup = thread->tl_joiner_cleans_up;
        }
@@ -461,9 +456,7 @@ _pthread_join(pthread_t thread, void **value_ptr, int conforming)
                res = EDEADLK;
        } else if (thread->tl_exit_gate == MACH_PORT_DEAD) {
                TAILQ_REMOVE(&__pthread_head, thread, tl_plist);
                res = EDEADLK;
        } else if (thread->tl_exit_gate == MACH_PORT_DEAD) {
                TAILQ_REMOVE(&__pthread_head, thread, tl_plist);
-#if DEBUG
-               PTHREAD_ASSERT(thread->tl_joiner_cleans_up);
-#endif
+               PTHREAD_DEBUG_ASSERT(thread->tl_joiner_cleans_up);
                thread->tl_joinable = false;
                if (value_ptr) *value_ptr = _pthread_get_exit_value(thread);
        } else {
                thread->tl_joinable = false;
                if (value_ptr) *value_ptr = _pthread_get_exit_value(thread);
        } else {
index 79e38baa07b6cdc481c3bc6762466fa61a58a603..725134fa2f45e34f44afb5f7b66cf6b46ca156e1 100644 (file)
@@ -470,6 +470,7 @@ _pthread_cond_wait(pthread_cond_t *ocond,
        volatile uint32_t *c_lseqcnt, *c_useqcnt, *c_sseqcnt;
        uint64_t oldval64, newval64, mugen, cvlsgen;
        uint32_t *npmtx = NULL;
        volatile uint32_t *c_lseqcnt, *c_useqcnt, *c_sseqcnt;
        uint64_t oldval64, newval64, mugen, cvlsgen;
        uint32_t *npmtx = NULL;
+       int timeout_elapsed = 0;
 
        res = _pthread_cond_check_init(cond, NULL);
        if (res != 0) {
 
        res = _pthread_cond_check_init(cond, NULL);
        if (res != 0) {
@@ -488,47 +489,59 @@ _pthread_cond_wait(pthread_cond_t *ocond,
 
        /* send relative time to kernel */
        if (abstime) {
 
        /* send relative time to kernel */
        if (abstime) {
+               if (abstime->tv_nsec < 0 || abstime->tv_nsec >= NSEC_PER_SEC) {
+                       return EINVAL;
+               }
+
                if (isRelative == 0) {
                        struct timespec now;
                        struct timeval tv;
                        __gettimeofday(&tv, NULL);
                        TIMEVAL_TO_TIMESPEC(&tv, &now);
 
                if (isRelative == 0) {
                        struct timespec now;
                        struct timeval tv;
                        __gettimeofday(&tv, NULL);
                        TIMEVAL_TO_TIMESPEC(&tv, &now);
 
-                       /* Compute relative time to sleep */
-                       then.tv_nsec = abstime->tv_nsec - now.tv_nsec;
-                       then.tv_sec = abstime->tv_sec - now.tv_sec;
-                       if (then.tv_nsec < 0) {
-                               then.tv_nsec += NSEC_PER_SEC;
-                               then.tv_sec--;
-                       }
-                       if (then.tv_sec < 0 || (then.tv_sec == 0 && then.tv_nsec == 0)) {
-                               return ETIMEDOUT;
-                       }
-                       if (conforming &&
-                           (abstime->tv_sec < 0 ||
-                            abstime->tv_nsec < 0 ||
-                            abstime->tv_nsec >= NSEC_PER_SEC)) {
-                               return EINVAL;
+                       if ((abstime->tv_sec == now.tv_sec) ?
+                               (abstime->tv_nsec <= now.tv_nsec) :
+                               (abstime->tv_sec < now.tv_sec)) {
+                               timeout_elapsed = 1;
+                       } else {
+                               /* Compute relative time to sleep */
+                               then.tv_nsec = abstime->tv_nsec - now.tv_nsec;
+                               then.tv_sec = abstime->tv_sec - now.tv_sec;
+                               if (then.tv_nsec < 0) {
+                                       then.tv_nsec += NSEC_PER_SEC;
+                                       then.tv_sec--;
+                               }
                        }
                } else {
                        then.tv_sec = abstime->tv_sec;
                        then.tv_nsec = abstime->tv_nsec;
                        if ((then.tv_sec == 0) && (then.tv_nsec == 0)) {
                        }
                } else {
                        then.tv_sec = abstime->tv_sec;
                        then.tv_nsec = abstime->tv_nsec;
                        if ((then.tv_sec == 0) && (then.tv_nsec == 0)) {
-                               return ETIMEDOUT;
+                               timeout_elapsed = 1;
                        }
                }
                        }
                }
-               if (conforming && (then.tv_sec < 0 || then.tv_nsec < 0)) {
-                       return EINVAL;
-               }
-               if (then.tv_nsec >= NSEC_PER_SEC) {
-                       return EINVAL;
-               }
        }
 
        if (cond->busy != NULL && cond->busy != mutex) {
                return EINVAL;
        }
 
        }
 
        if (cond->busy != NULL && cond->busy != mutex) {
                return EINVAL;
        }
 
+       /*
+        * If timeout is known to have elapsed, we still need to unlock and
+        * relock the mutex to allow other waiters to get in line and
+        * modify the condition state.
+        */
+        if (timeout_elapsed) {
+               res = pthread_mutex_unlock(omutex);
+               if (res != 0) {
+                       return res;
+               }
+               res = pthread_mutex_lock(omutex);
+               if (res != 0) {
+                       return res;
+               }
+               return ETIMEDOUT;
+       }
+
        COND_GETSEQ_ADDR(cond, &c_lsseqaddr, &c_lseqcnt, &c_useqcnt, &c_sseqcnt);
 
        do {
        COND_GETSEQ_ADDR(cond, &c_lsseqaddr, &c_lseqcnt, &c_useqcnt, &c_sseqcnt);
 
        do {
index 7a8d500f110085bad758dd569abf3388b0c7233e..3126c3b8a4973189356c8790466762826b815a49 100644 (file)
@@ -2,9 +2,9 @@
 #include <fcntl.h>
 #include <unistd.h>
 
 #include <fcntl.h>
 #include <unistd.h>
 
-extern int __pthread_chdir(char *path);
+extern int __pthread_chdir(const char *path);
 int
 int
-pthread_chdir_np(char *path)
+pthread_chdir_np(const char *path)
 {
        return __pthread_chdir(path);
 }
 {
        return __pthread_chdir(path);
 }
index 282dfc3dffd8691fbdb1f8141be820a1846d7044..3836f15988500b679fa81b512c880384cc233d59 100644 (file)
@@ -91,8 +91,9 @@ pthread_dependency_wait_np(pthread_dependency_t *pr)
                                pr->__pdep_owner, 0);
                switch (-ret) {
                case EFAULT:
                                pr->__pdep_owner, 0);
                switch (-ret) {
                case EFAULT:
-                       if (pr->__pdep_opaque1 == pr->__pdep_owner) goto again;
+               case EINTR:
                case 0:
                case 0:
+                       if (pr->__pdep_opaque1 == pr->__pdep_owner) goto again;
                        break;
                case EOWNERDEAD:
                        PTHREAD_CLIENT_CRASH(pr->__pdep_owner, "Waiting on orphaned dependency");
                        break;
                case EOWNERDEAD:
                        PTHREAD_CLIENT_CRASH(pr->__pdep_owner, "Waiting on orphaned dependency");
index edc97ee38cbcdb10948eed3da81fd43d4f748084..e1e5c2e042f9714b2174d55195d7c41b6328fa75 100644 (file)
@@ -131,7 +131,6 @@ void
 _pthread_mutex_global_init(const char *envp[],
                struct _pthread_registration_data *registration_data)
 {
 _pthread_mutex_global_init(const char *envp[],
                struct _pthread_registration_data *registration_data)
 {
-
        int opt = _PTHREAD_MTX_OPT_POLICY_DEFAULT;
        if (registration_data->mutex_default_policy) {
                int policy = registration_data->mutex_default_policy;
        int opt = _PTHREAD_MTX_OPT_POLICY_DEFAULT;
        if (registration_data->mutex_default_policy) {
                int policy = registration_data->mutex_default_policy;
@@ -461,8 +460,8 @@ PTHREAD_NOEXPORT PTHREAD_NOINLINE PTHREAD_NORETURN
 int
 _pthread_mutex_corruption_abort(_pthread_mutex *mutex)
 {
 int
 _pthread_mutex_corruption_abort(_pthread_mutex *mutex)
 {
-       PTHREAD_ABORT("pthread_mutex corruption: mutex owner changed in the "
-                       "middle of lock/unlock");
+       PTHREAD_CLIENT_CRASH(0, "pthread_mutex corruption: mutex owner changed "
+                       "in the middle of lock/unlock");
 }
 
 
 }
 
 
@@ -941,7 +940,7 @@ _pthread_mutex_fairshare_unlock_drop(_pthread_mutex *mutex, mutex_seq newseq,
                        res = 0;
                }
                if (res != 0) {
                        res = 0;
                }
                if (res != 0) {
-                       PTHREAD_ABORT("__psynch_mutexdrop failed with error %d", res);
+                       PTHREAD_INTERNAL_CRASH(res, "__psynch_mutexdrop failed");
                }
                return res;
        }
                }
                return res;
        }
@@ -1122,7 +1121,7 @@ _pthread_mutex_firstfit_wake(_pthread_mutex *mutex, mutex_seq newseq,
                        res = 0;
                }
                if (res != 0) {
                        res = 0;
                }
                if (res != 0) {
-                       PTHREAD_ABORT("__psynch_mutexdrop failed with error %d", res);
+                       PTHREAD_INTERNAL_CRASH(res, "__psynch_mutexdrop failed");
                }
                return res;
        }
                }
                return res;
        }
index 5b0bc9a70916ccf5a155683294dcbed23f0fd301..dac212ab4743d72df90348b75fce1c2098345646 100644 (file)
@@ -199,7 +199,16 @@ rwlock_seq_atomic_load_relaxed(rwlock_seq *seqaddr, rwlock_seq *oldseqval,
        switch (seqfields) {
        case RWLOCK_SEQ_LSU:
 #if RWLOCK_USE_INT128
        switch (seqfields) {
        case RWLOCK_SEQ_LSU:
 #if RWLOCK_USE_INT128
+#if defined(__arm64__) && defined(__ARM_ARCH_8_2__)
+               // Workaround clang armv81 codegen bug for 128bit os_atomic_load
+               // rdar://problem/31213932
+               oldseqval->seq_LSU = seqaddr->seq_LSU;
+               while (!os_atomic_cmpxchgvw(&seqaddr->atomic_seq_LSU,
+                               oldseqval->seq_LSU, oldseqval->seq_LSU, &oldseqval->seq_LSU,
+                               relaxed));
+#else
                oldseqval->seq_LSU = os_atomic_load(&seqaddr->atomic_seq_LSU, relaxed);
                oldseqval->seq_LSU = os_atomic_load(&seqaddr->atomic_seq_LSU, relaxed);
+#endif
 #else
                oldseqval->seq_LS = os_atomic_load(&seqaddr->atomic_seq_LS, relaxed);
                oldseqval->seq_U = os_atomic_load(&seqaddr->atomic_seq_U, relaxed);
 #else
                oldseqval->seq_LS = os_atomic_load(&seqaddr->atomic_seq_LS, relaxed);
                oldseqval->seq_U = os_atomic_load(&seqaddr->atomic_seq_U, relaxed);
@@ -673,8 +682,7 @@ _pthread_rwlock_lock_wait(pthread_rwlock_t *orwlock, bool readlock,
                PLOCKSTAT_RW_BLOCKED(orwlock, plockstat, BLOCK_SUCCESS_PLOCKSTAT);
        } else {
                PLOCKSTAT_RW_BLOCKED(orwlock, plockstat, BLOCK_FAIL_PLOCKSTAT);
                PLOCKSTAT_RW_BLOCKED(orwlock, plockstat, BLOCK_SUCCESS_PLOCKSTAT);
        } else {
                PLOCKSTAT_RW_BLOCKED(orwlock, plockstat, BLOCK_FAIL_PLOCKSTAT);
-               PTHREAD_ABORT("kernel rwlock returned unknown error %x: "
-                               "tid %llx\n", res, _pthread_selfid_direct());
+               PTHREAD_INTERNAL_CRASH(res, "kernel rwlock returned unknown error");
        }
 
        return res;
        }
 
        return res;
@@ -930,8 +938,7 @@ _pthread_rwlock_unlock_drop(pthread_rwlock_t *orwlock, rwlock_seq oldseq,
        } while (res == EINTR);
 
        if (res != 0) {
        } while (res == EINTR);
 
        if (res != 0) {
-               PTHREAD_ABORT("kernel rwunlock returned unknown error %x: "
-                               "tid %llx\n", res, _pthread_selfid_direct());
+               PTHREAD_INTERNAL_CRASH(res, "kernel rwunlock returned unknown error");
        }
 
        return res;
        }
 
        return res;
diff --git a/src/pthread_support.c b/src/pthread_support.c
deleted file mode 100644 (file)
index f8c529f..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "internal.h"
-#include <dlfcn.h>
-#include <_simple.h>
-
-
-#define __SIGABRT 6
-
-/* We should move abort() into Libsyscall, if possible. */
-int __getpid(void);
-
-int
-__kill(int pid, int signum, int posix);
-
-void
-__pthread_abort(void)
-{
-       PTHREAD_NORETURN void (*_libc_abort)(void);
-       _libc_abort = dlsym(RTLD_DEFAULT, "abort");
-
-       if (_libc_abort) {
-               _libc_abort();
-       } else {
-               __kill(__getpid(), __SIGABRT, 0);
-       }
-       __builtin_trap();
-}
-
-void
-__pthread_abort_reason(const char *fmt, ...)
-{
-       __pthread_abort();
-}
index 54b1bb020d060eedc48e723f994af6a0c49e81e1..b8e5d1aeef0dc3ce826a13fe94cea2547f5b5f2a 100644 (file)
 #include "internal.h"
 #include <TargetConditionals.h>
 
 #include "internal.h"
 #include <TargetConditionals.h>
 
+#ifndef PTHREAD_KEY_LEGACY_SUPPORT
+#if TARGET_OS_DRIVERKIT
+#define PTHREAD_KEY_LEGACY_SUPPORT 0
+#else
+#define PTHREAD_KEY_LEGACY_SUPPORT 1
+#endif // TARGET_OS_DRIVERKIT
+#endif // PTHREAD_KEY_LEGACY_SUPPORT
+
 #if !VARIANT_DYLD
 // __pthread_tsd_first is first static key managed by libpthread.
 // __pthread_tsd_max is the (observed) end of static key destructors.
 #if !VARIANT_DYLD
 // __pthread_tsd_first is first static key managed by libpthread.
 // __pthread_tsd_max is the (observed) end of static key destructors.
@@ -66,8 +74,13 @@ static const int __pthread_tsd_end = _INTERNAL_POSIX_THREAD_KEYS_END;
 
 static int __pthread_tsd_max = __pthread_tsd_first;
 static _pthread_lock __pthread_tsd_lock = _PTHREAD_LOCK_INITIALIZER;
 
 static int __pthread_tsd_max = __pthread_tsd_first;
 static _pthread_lock __pthread_tsd_lock = _PTHREAD_LOCK_INITIALIZER;
+#if PTHREAD_KEY_LEGACY_SUPPORT
 static bool __pthread_key_legacy_behaviour = 0;
 static bool __pthread_key_legacy_behaviour_log = 0;
 static bool __pthread_key_legacy_behaviour = 0;
 static bool __pthread_key_legacy_behaviour_log = 0;
+#else
+#define __pthread_key_legacy_behaviour 0
+#define _pthread_tsd_cleanup_legacy(...)
+#endif // PTHREAD_KEY_LEGACY_SUPPORT
 
 // Omit support for pthread key destructors in the static archive for dyld.
 // dyld does not create and destroy threads so these are not necessary.
 
 // Omit support for pthread key destructors in the static archive for dyld.
 // dyld does not create and destroy threads so these are not necessary.
@@ -86,12 +99,14 @@ static struct {
 void
 _pthread_key_global_init(const char *envp[])
 {
 void
 _pthread_key_global_init(const char *envp[])
 {
+#if PTHREAD_KEY_LEGACY_SUPPORT
        if (_simple_getenv(envp, "PTHREAD_KEY_LEGACY_DESTRUCTOR_ORDER")) {
                __pthread_key_legacy_behaviour = true;
        }
        if (_simple_getenv(envp, "PTHREAD_KEY_LEGACY_DESTRUCTOR_ORDER_LOG")) {
                __pthread_key_legacy_behaviour_log = true;
        }
        if (_simple_getenv(envp, "PTHREAD_KEY_LEGACY_DESTRUCTOR_ORDER")) {
                __pthread_key_legacy_behaviour = true;
        }
        if (_simple_getenv(envp, "PTHREAD_KEY_LEGACY_DESTRUCTOR_ORDER_LOG")) {
                __pthread_key_legacy_behaviour_log = true;
        }
+#endif // PTHREAD_KEY_LEGACY_SUPPORT
 }
 
 // Returns true if successful, false if destructor was already set.
 }
 
 // Returns true if successful, false if destructor was already set.
@@ -239,9 +254,6 @@ _pthread_tsd_cleanup_key(pthread_t self, pthread_key_t key)
 }
 #endif // !VARIANT_DYLD
 
 }
 #endif // !VARIANT_DYLD
 
-#import <_simple.h>
-#import <dlfcn.h>
-
 #if !VARIANT_DYLD
 static void
 _pthread_tsd_cleanup_new(pthread_t self)
 #if !VARIANT_DYLD
 static void
 _pthread_tsd_cleanup_new(pthread_t self)
@@ -263,6 +275,9 @@ _pthread_tsd_cleanup_new(pthread_t self)
        self->max_tsd_key = 0;
 }
 
        self->max_tsd_key = 0;
 }
 
+#if PTHREAD_KEY_LEGACY_SUPPORT
+#import <_simple.h>
+#import <dlfcn.h>
 static void
 _pthread_tsd_behaviour_check(pthread_t self)
 {
 static void
 _pthread_tsd_behaviour_check(pthread_t self)
 {
@@ -320,6 +335,7 @@ _pthread_tsd_cleanup_legacy(pthread_t self)
                }
        }
 }
                }
        }
 }
+#endif // PTHREAD_KEY_LEGACY_SUPPORT
 #endif // !VARIANT_DYLD
 
 void
 #endif // !VARIANT_DYLD
 
 void
index ef360896e694091bf3b2d021a3132c6d26d53d7e..8aef21b45edd816916007f854cfbc0d8ac8fb4b0 100644 (file)
--- a/src/qos.c
+++ b/src/qos.c
@@ -201,7 +201,7 @@ _pthread_qos_class_encode_workqueue(int queue_priority, unsigned long flags)
        case WORKQ_LOW_PRIOQUEUE:       qos = THREAD_QOS_UTILITY; break;
        case WORKQ_BG_PRIOQUEUE:        qos = THREAD_QOS_BACKGROUND; break;
        default:
        case WORKQ_LOW_PRIOQUEUE:       qos = THREAD_QOS_UTILITY; break;
        case WORKQ_BG_PRIOQUEUE:        qos = THREAD_QOS_BACKGROUND; break;
        default:
-               __pthread_abort();
+               PTHREAD_CLIENT_CRASH(queue_priority, "Invalid priority");
        }
        return _pthread_priority_make_from_thread_qos(qos, 0, flags);
 }
        }
        return _pthread_priority_make_from_thread_qos(qos, 0, flags);
 }
@@ -218,7 +218,7 @@ _pthread_set_properties_self(_pthread_set_flags_t flags,
        _pthread_set_flags_t kflags = flags;
        int rv = 0;
 
        _pthread_set_flags_t kflags = flags;
        int rv = 0;
 
-       if (self->wqoutsideqos && (flags & _PTHREAD_SET_SELF_OUTSIDE_QOS_SKIP)) {
+       if (self->wq_outsideqos && (flags & _PTHREAD_SET_SELF_OUTSIDE_QOS_SKIP)) {
                // A number of properties cannot be altered if we are a workloop
                // thread that has outside of QoS properties applied to it.
                kflags &= ~_PTHREAD_SET_SELF_OUTSIDE_QOS_SKIP;
                // A number of properties cannot be altered if we are a workloop
                // thread that has outside of QoS properties applied to it.
                kflags &= ~_PTHREAD_SET_SELF_OUTSIDE_QOS_SKIP;
diff --git a/src/thread_setup.c b/src/thread_setup.c
deleted file mode 100644 (file)
index 22cc689..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2000-2003, 2008, 2012 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- *              All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-#include "internal.h"
-
-#if !defined(__OPEN_SOURCE__) && TARGET_OS_OSX // 40703288
-/*
- * Machine specific support for thread initialization
- */
-
-// NOTE: no resolvers, so this file must not contain any atomic operations
-
-PTHREAD_NOEXPORT void _pthread_setup_suspended(pthread_t th, void (*f)(pthread_t), void *sp);
-
-/*
- * Set up the initial state of a MACH thread
- */
-void
-_pthread_setup_suspended(pthread_t thread,
-              void (*routine)(pthread_t),
-              void *vsp)
-{
-#if defined(__i386__)
-       i386_thread_state_t state = { };
-       thread_state_flavor_t flavor = x86_THREAD_STATE32;
-       mach_msg_type_number_t count = i386_THREAD_STATE_COUNT;
-#elif defined(__x86_64__)
-       x86_thread_state64_t state = { };
-       thread_state_flavor_t flavor = x86_THREAD_STATE64;
-       mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
-#else
-#error _pthread_setup not defined for this architecture
-#endif
-
-       (void)thread_get_state(_pthread_kernel_thread(thread),
-                       flavor, (thread_state_t)&state, &count);
-
-#if defined(__i386__)
-       uintptr_t *sp = vsp;
-
-       state.__eip = (uintptr_t)routine;
-
-       // We need to simulate a 16-byte aligned stack frame as if we had
-       // executed a call instruction. Since we're "pushing" one argument,
-       // we need to adjust the pointer by 12 bytes (3 * sizeof (int *))
-       sp -= 3;                        // make sure stack is aligned
-       *--sp = (uintptr_t)thread;      // argument to function
-       *--sp = 0;                      // fake return address
-       state.__esp = (uintptr_t)sp;    // set stack pointer
-#elif defined(__x86_64__)
-       uintptr_t *sp = vsp;
-
-       state.__rip = (uintptr_t)routine;
-
-       // We need to simulate a 16-byte aligned stack frame as if we had
-       // executed a call instruction. The stack should already be aligned
-       // before it comes to us and we don't need to push any arguments,
-       // so we shouldn't need to change it.
-       state.__rdi = (uintptr_t)thread;        // argument to function
-       *--sp = 0;                              // fake return address
-       state.__rsp = (uintptr_t)sp;            // set stack pointer
-#else
-#error _pthread_setup_suspended not defined for this architecture
-#endif
-
-       (void)thread_set_state(_pthread_kernel_thread(thread), flavor, (thread_state_t)&state, count);
-}
-#endif // !defined(__OPEN_SOURCE__) && TARGET_OS_OSX
index d33af6bc0798f2580c9e6376552013984bfec655..2aa7dcd5c65306d9f3fe1578c9153ce14344728a 100644 (file)
--- a/sys/qos.h
+++ b/sys/qos.h
 #define __QOS_ENUM(name, type, ...) enum { __VA_ARGS__ }; typedef type name##_t
 #define __QOS_CLASS_AVAILABLE(...)
 
 #define __QOS_ENUM(name, type, ...) enum { __VA_ARGS__ }; typedef type name##_t
 #define __QOS_CLASS_AVAILABLE(...)
 
+#if defined(__cplusplus) || defined(__OBJC__) || __LP64__
 #if defined(__has_feature) && defined(__has_extension)
 #if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
 #undef __QOS_ENUM
 #define __QOS_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t
 #endif
 #if defined(__has_feature) && defined(__has_extension)
 #if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
 #undef __QOS_ENUM
 #define __QOS_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t
 #endif
+#endif
 #if __has_feature(enumerator_attributes)
 #undef __QOS_CLASS_AVAILABLE
 #define __QOS_CLASS_AVAILABLE __API_AVAILABLE
 #if __has_feature(enumerator_attributes)
 #undef __QOS_CLASS_AVAILABLE
 #define __QOS_CLASS_AVAILABLE __API_AVAILABLE
index 0a3892635d3c582c28728b16f59f1ea4adc635de..b968f87e2aefcabaa38452e1b15f344b09dd35e6 100644 (file)
@@ -35,6 +35,6 @@
  * system responsiveness for the user.
  * This is SPI for use by Spotlight and Time Machine only.
  */
  * system responsiveness for the user.
  * This is SPI for use by Spotlight and Time Machine only.
  */
-#define QOS_CLASS_MAINTENANCE  0x05
+#define QOS_CLASS_MAINTENANCE  ((qos_class_t)0x05)
 
 #endif //_QOS_SYS_PRIVATE_H
 
 #endif //_QOS_SYS_PRIVATE_H
index 84e2717439c7292b53be73eb0518e6020ea781d4..f41b8730698264c3e0a9b56339989c401524c69a 100644 (file)
@@ -33,6 +33,7 @@ TARGETS += once_cancel
 TARGETS += pthread_attr_setstacksize
 TARGETS += pthread_bulk_create
 TARGETS += pthread_cancel
 TARGETS += pthread_attr_setstacksize
 TARGETS += pthread_bulk_create
 TARGETS += pthread_cancel
+TARGETS += pthread_create_from_mach_thread
 TARGETS += pthread_cwd
 TARGETS += pthread_exit
 TARGETS += pthread_introspection
 TARGETS += pthread_cwd
 TARGETS += pthread_exit
 TARGETS += pthread_introspection
@@ -46,6 +47,7 @@ TARGETS += rdar_32848402
 #TARGETS += rwlock-signal
 #TARGETS += rwlock
 TARGETS += tsd
 #TARGETS += rwlock-signal
 #TARGETS += rwlock
 TARGETS += tsd
+TARGETS += setrlimit_sigsegv
 #TARGETS += wq_block_handoff
 #TARGETS += wq_event_manager
 #TARGETS += wq_kevent
 #TARGETS += wq_block_handoff
 #TARGETS += wq_event_manager
 #TARGETS += wq_kevent
@@ -54,6 +56,9 @@ TARGETS += wq_limits
 TARGETS += add_timer_termination
 TARGETS += perf_contended_mutex_rwlock
 
 TARGETS += add_timer_termination
 TARGETS += perf_contended_mutex_rwlock
 
+# this should be CUSTOM_TARGETS, see "Compatibility defines" in Makefile.targets
+OTHER_TARGETS := stackoverflow_crash
+
 OTHER_LTE_INCLUDE_FILES += \
        /usr/local/lib/libdarwintest_utils.dylib
 
 OTHER_LTE_INCLUDE_FILES += \
        /usr/local/lib/libdarwintest_utils.dylib
 
@@ -75,3 +80,12 @@ main_stack_custom: OTHER_CFLAGS += -DSTACKSIZE=0x124000
 bsdthread_set_self: OTHER_CFLAGS += -D_DARWIN_FEATURE_CLOCK_GETTIME
 
 include $(DEVELOPER_DIR)/AppleInternal/Makefiles/darwintest/Makefile.targets
 bsdthread_set_self: OTHER_CFLAGS += -D_DARWIN_FEATURE_CLOCK_GETTIME
 
 include $(DEVELOPER_DIR)/AppleInternal/Makefiles/darwintest/Makefile.targets
+
+stackoverflow_crash: helpers/stackoverflow_crash.c
+       mkdir -p $(SYMROOT)/assets/
+       $(CC) -o $(SYMROOT)/assets/$@ $(CFLAGS) -D_POSIX_C_SOURCE=1 $(OTHER_CFLAGS) $(LDFLAGS) $(OTHER_LDFLAGS)  $<
+       env CODESIGN_ALLOCATE=$(CODESIGN_ALLOCATE) $(CODESIGN) --force --sign - --timestamp=none $(SYMROOT)/assets/$@
+
+install-stackoverflow_crash: stackoverflow_crash
+       mkdir -p $(INSTALLDIR)/assets
+       @cp $(SYMROOT)/assets/stackoverflow_crash $(INSTALLDIR)/assets
index 3f3c4e7a1d6ced1e7566802e86bafc1eeaf4baba..89734e9aad754c4cf3093eccd4ade24efd05d006 100644 (file)
@@ -13,6 +13,7 @@
 #include "darwintest_defaults.h"
 
 #define NUM_THREADS 8
 #include "darwintest_defaults.h"
 
 #define NUM_THREADS 8
+#define RDAR_38144536 1
 
 struct context {
        pthread_cond_t cond;
 
 struct context {
        pthread_cond_t cond;
@@ -162,17 +163,29 @@ T_DECL(cond_timedwait_nulltimeout, "pthread_cond_timedwait() with NULL timeout,
 
 T_DECL(cond_timedwait_zerotimeout, "pthread_cond_timedwait() with zero timeout, ensure mutex is unlocked")
 {
 
 T_DECL(cond_timedwait_zerotimeout, "pthread_cond_timedwait() with zero timeout, ensure mutex is unlocked")
 {
+#if RDAR_38144536
+       T_SKIP("skipped <rdar://38144536>");
+#else // RDAR_38144536
        cond_timedwait_timeouts_internal(eZeroTimeout, false);
        cond_timedwait_timeouts_internal(eZeroTimeout, false);
+#endif // RDAR_38144536
 }
 
 T_DECL(cond_timedwait_beforeepochtimeout, "pthread_cond_timedwait() with timeout before the epoch, ensure mutex is unlocked")
 {
 }
 
 T_DECL(cond_timedwait_beforeepochtimeout, "pthread_cond_timedwait() with timeout before the epoch, ensure mutex is unlocked")
 {
+#if RDAR_38144536
+       T_SKIP("skipped <rdar://38144536>");
+#else // RDAR_38144536
        cond_timedwait_timeouts_internal(eBeforeEpochTimeout, false);
        cond_timedwait_timeouts_internal(eBeforeEpochTimeout, false);
+#endif // RDAR_38144536
 }
 
 T_DECL(cond_timedwait_pasttimeout, "pthread_cond_timedwait() with timeout in the past, ensure mutex is unlocked")
 {
 }
 
 T_DECL(cond_timedwait_pasttimeout, "pthread_cond_timedwait() with timeout in the past, ensure mutex is unlocked")
 {
+#if RDAR_38144536
+       T_SKIP("skipped <rdar://38144536>");
+#else // RDAR_38144536
        cond_timedwait_timeouts_internal(eRecentPastTimeout, false);
        cond_timedwait_timeouts_internal(eRecentPastTimeout, false);
+#endif // RDAR_38144536
 }
 
 T_DECL(cond_timedwait_relative_nulltimeout, "pthread_cond_timedwait_relative_np() with relative NULL timeout, ensure mutex is unlocked")
 }
 
 T_DECL(cond_timedwait_relative_nulltimeout, "pthread_cond_timedwait_relative_np() with relative NULL timeout, ensure mutex is unlocked")
diff --git a/tests/helpers/stackoverflow_crash.c b/tests/helpers/stackoverflow_crash.c
new file mode 100644 (file)
index 0000000..2858033
--- /dev/null
@@ -0,0 +1,56 @@
+#include<stdio.h>
+#include<sys/resource.h>
+
+static volatile int * array1_ref = NULL;
+static long last_stack_addr = 0;
+
+static void
+recursive_fn(void)
+{
+       volatile int array1[1024]; /* leave this as it is */
+       int addr;
+       last_stack_addr = (long)&addr;
+       array1_ref = array1; /* make sure compiler cannot discard storage */
+       array1[0] = 0;
+       if (array1_ref == 0) {
+               /* fool clang -Winfinite-recursion */
+               return;
+       }
+       recursive_fn();
+       return;
+}
+
+int
+main(__unused int argc, __unused const char *argv[])
+{
+       struct rlimit save;
+
+       if (getrlimit(RLIMIT_STACK, &save) == -1) {
+               printf("child: ERROR - getrlimit");
+               return 2;
+       }
+       printf("child: LOG - current stack limits cur=0x%llx, max=0x%llx, inf=0x%llx\n", save.rlim_cur, save.rlim_max, RLIM_INFINITY);
+
+       if(save.rlim_cur >= save.rlim_max) {
+               printf("child: ERROR - invalid limits");
+               return 2;
+       }
+
+       if(save.rlim_max == RLIM_INFINITY) {
+               printf("child: ERROR - rlim_max = RLIM_INFINITY");
+               return 2;
+       }
+
+       save.rlim_cur += 4;
+
+       printf("child: LOG - Raising setrlimit rlim_cur=0x%llx, rlim_max=0x%llx\n", save.rlim_cur, save.rlim_max);
+
+       if (setrlimit(RLIMIT_STACK, &save) == -1) {
+               printf("child: ERROR - Raising the limits failed.");
+               return 2;
+       }
+
+       printf("child: LOG - Make the stack grow such that a SIGSEGV is generated.\n");
+       recursive_fn();
+       return 0;
+}
diff --git a/tests/pthread_create_from_mach_thread.c b/tests/pthread_create_from_mach_thread.c
new file mode 100644 (file)
index 0000000..0f4fc91
--- /dev/null
@@ -0,0 +1,93 @@
+
+#include <pthread.h>
+#include <mach/mach.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread_spis.h>
+
+#include "darwintest_defaults.h"
+
+#define CHILD_STACK_COUNT 1024
+static uint64_t child_stack[CHILD_STACK_COUNT];
+
+static void*
+pthread_runner(void* __unused arg)
+{
+    T_PASS("mach -> pthread conversion successful");
+    T_END;
+}
+
+static void *
+mach_bootstrap(void * __unused arg)
+{
+    pthread_t thread;
+    pthread_create_from_mach_thread(&thread, NULL, pthread_runner, NULL);
+    while (1) {
+        swtch_pri(0); // mach_yield
+    }
+}
+
+T_DECL(pthread_create_from_mach_thread, "pthread_create_from_mach_thread",
+       T_META_ALL_VALID_ARCHS(YES),
+       // Having leaks running will suppress the behavior we are testing
+       T_META_CHECK_LEAKS(false),
+       T_META_ENVVAR("MallocStackLogging=1")
+    )
+{
+    T_PASS("MallocStackLogging: %s", getenv("MallocStackLogging"));
+
+    // Create a mach_thread to start with
+    mach_port_t task = mach_task_self();
+
+    thread_state_flavor_t flavor;
+    mach_msg_type_number_t count;
+
+    uintptr_t start_addr = (uintptr_t)&mach_bootstrap;
+    // Force alignment to 16-bytes
+    uintptr_t stack_top = ((uintptr_t)&child_stack[CHILD_STACK_COUNT]) & ~0xf;
+
+#if defined(__x86_64__)
+    T_PASS("x86_64");
+    flavor = x86_THREAD_STATE64;
+    count = x86_THREAD_STATE64_COUNT;
+    x86_thread_state64_t state = {
+        .__rip = start_addr,
+        // Must be 16-byte-off-by-8 aligned <rdar://problem/15886599>
+        .__rsp = stack_top - 8,
+    };
+#elif defined(__arm64__)
+    T_PASS("arm64");
+    flavor = ARM_THREAD_STATE64;
+    count = ARM_THREAD_STATE64_COUNT;
+    arm_thread_state64_t state = { };
+    arm_thread_state64_set_pc_fptr(state, &mach_bootstrap);
+    arm_thread_state64_set_sp(state, stack_top);
+    (void)start_addr;
+#elif defined(__arm__)
+    T_PASS("arm (32)");
+    flavor = ARM_THREAD_STATE;
+    count = ARM_THREAD_STATE_COUNT;
+    arm_thread_state_t state = {
+        .__pc = start_addr,
+        .__sp = stack_top,
+        .__cpsr = 0x20,
+    };
+#else
+#error Unknown architecture
+#endif
+
+    thread_state_t state_ptr = (thread_state_t)&state;
+    thread_t task_thread;
+    T_PASS("Launching Thread");
+
+    kern_return_t ret = thread_create_running(task, flavor, state_ptr, count, &task_thread);
+    T_ASSERT_MACH_SUCCESS(ret, "mach thread created");
+    // Wait forever
+    sigset_t empty;
+    T_QUIET; T_ASSERT_POSIX_ZERO(sigemptyset(&empty), NULL);
+    while (sigsuspend(&empty)) {
+        continue;
+    }
+    T_FAIL("Didn't wait forever?");
+}
index 46eb527136fb58bd305982be4d5ed5cff71a610c..9529f2633a1556b71ea39e4b62e88916e0e00767 100644 (file)
@@ -8,7 +8,7 @@
 
 extern __uint64_t __thread_selfid( void );
 
 
 extern __uint64_t __thread_selfid( void );
 
-static void *do_test(void * __unused arg)
+static void *do_test(void * arg)
 {
        uint64_t threadid = __thread_selfid();
        T_ASSERT_NE(threadid, (uint64_t)0, "__thread_selfid()");
 {
        uint64_t threadid = __thread_selfid();
        T_ASSERT_NE(threadid, (uint64_t)0, "__thread_selfid()");
@@ -21,6 +21,9 @@ static void *do_test(void * __unused arg)
        pth_threadid = _pthread_threadid_self_np_direct();
        T_EXPECT_EQ(threadid, pth_threadid, "pthread_threadid_np_direct()");
 
        pth_threadid = _pthread_threadid_self_np_direct();
        T_EXPECT_EQ(threadid, pth_threadid, "pthread_threadid_np_direct()");
 
+       if (arg) {
+               *(uint64_t *)arg = pth_threadid;
+       }
        return NULL;
 }
 
        return NULL;
 }
 
@@ -31,9 +34,14 @@ T_DECL(pthread_threadid_np, "pthread_threadid_np",
        do_test(NULL);
 
        T_LOG("Pthread");
        do_test(NULL);
 
        T_LOG("Pthread");
-       pthread_t pth;
-       T_ASSERT_POSIX_ZERO(pthread_create(&pth, NULL, do_test, NULL), NULL);
-       T_ASSERT_POSIX_ZERO(pthread_join(pth, NULL), NULL);
+       for (int i = 0; i < 100; i++) {
+               uint64_t tid1 = 0, tid2 = 0;
+               pthread_t pth;
+               T_ASSERT_POSIX_ZERO(pthread_create(&pth, NULL, do_test, &tid1), NULL);
+               T_EXPECT_POSIX_ZERO(pthread_threadid_np(pth, &tid2), NULL);
+               T_ASSERT_POSIX_ZERO(pthread_join(pth, NULL), NULL);
+               T_EXPECT_EQ(tid1, tid2, "parent and child agree");
+       }
 
        T_LOG("Workqueue Thread");
        dispatch_queue_t dq = dispatch_queue_create("myqueue", NULL);
 
        T_LOG("Workqueue Thread");
        dispatch_queue_t dq = dispatch_queue_create("myqueue", NULL);
diff --git a/tests/setrlimit_sigsegv.c b/tests/setrlimit_sigsegv.c
new file mode 100644 (file)
index 0000000..8f578d5
--- /dev/null
@@ -0,0 +1,52 @@
+#include "darwintest_defaults.h"
+#include <spawn.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+
+
+extern char **environ;
+
+T_DECL(setrlimit_overflow_segfault,
+               "sigsegv is sent when stack(limit set with setrlimit) is fully used.",
+               T_META_IGNORECRASHES(".*stackoverflow_crash.*"),
+               T_META_CHECK_LEAKS(NO),
+               T_META_ALL_VALID_ARCHS(YES),
+               T_META_ASROOT(YES))
+{
+       pid_t child_pid = 0;
+       int rv = 0;
+
+       struct rlimit lim, save;
+       T_ASSERT_POSIX_SUCCESS(getrlimit(RLIMIT_STACK, &save), NULL);
+       T_ASSERT_POSIX_SUCCESS(getrlimit(RLIMIT_STACK, &lim), NULL);
+       T_LOG("parent: stack limits cur=%llx max=%llx", lim.rlim_cur, lim.rlim_max);
+       lim.rlim_cur = lim.rlim_cur/8;
+       T_ASSERT_POSIX_SUCCESS(setrlimit(RLIMIT_STACK, &lim), NULL);
+       int status = 0;
+       int exit_signal = 0;
+
+       char *crash_cmd[] = { "./assets/stackoverflow_crash", NULL };
+       posix_spawn_file_actions_t fact;
+       posix_spawn_file_actions_init(&fact);
+       T_ASSERT_POSIX_SUCCESS(posix_spawn_file_actions_addinherit_np(&fact, STDIN_FILENO), NULL);
+       T_ASSERT_POSIX_SUCCESS(posix_spawn_file_actions_addinherit_np(&fact, STDOUT_FILENO), NULL);
+       T_ASSERT_POSIX_SUCCESS(posix_spawn_file_actions_addinherit_np(&fact, STDERR_FILENO), NULL);
+       T_LOG("spawning %s", crash_cmd[0]);
+       rv = posix_spawn(&child_pid, crash_cmd[0], &fact, NULL, crash_cmd, environ);
+       T_ASSERT_POSIX_SUCCESS(rv, "spawning the stackoverflow program");
+
+       T_LOG("parent: waiting for child process with pid %d", child_pid);
+       wait(&status);
+       T_LOG("parent: child process exited. status=%d", WEXITSTATUS(status));
+
+
+       T_ASSERT_POSIX_SUCCESS(setrlimit(RLIMIT_STACK, &save), "Restore original limtis");
+       posix_spawn_file_actions_destroy(&fact);
+
+       T_ASSERT_TRUE(WIFSIGNALED(status), "child exit with a signal");
+       exit_signal = WTERMSIG(status);
+       T_ASSERT_EQ(exit_signal, SIGSEGV, "child should receive SIGSEGV");
+
+       return;
+}
index f910b286a12b3224ed8d13d21c61e49ce4a910f9..f9458adc2722484ead2c2771c18b7c9a9a294ff4 100644 (file)
@@ -8,17 +8,14 @@
 #define call_chkstk(value) \
                __asm__ volatile("orr x9, xzr, %0\t\n" \
                                "bl _thread_chkstk_darwin" : : "i"(value) : "x9")
 #define call_chkstk(value) \
                __asm__ volatile("orr x9, xzr, %0\t\n" \
                                "bl _thread_chkstk_darwin" : : "i"(value) : "x9")
-#define TRAPSIG SIGTRAP
 #elif defined(__x86_64__)
 #define call_chkstk(value) \
                __asm__ volatile("movq %0, %%rax\t\n" \
                                "callq _thread_chkstk_darwin" : : "i"(value) : "rax")
 #elif defined(__x86_64__)
 #define call_chkstk(value) \
                __asm__ volatile("movq %0, %%rax\t\n" \
                                "callq _thread_chkstk_darwin" : : "i"(value) : "rax")
-#define TRAPSIG SIGILL
 #elif defined(__i386__)
 #define call_chkstk(value) \
                __asm__ volatile("movl %0, %%eax\t\n" \
                                "calll _thread_chkstk_darwin" : : "i"(value) : "eax")
 #elif defined(__i386__)
 #define call_chkstk(value) \
                __asm__ volatile("movl %0, %%eax\t\n" \
                                "calll _thread_chkstk_darwin" : : "i"(value) : "eax")
-#define TRAPSIG SIGILL
 #endif
 
 static void
 #endif
 
 static void
@@ -41,7 +38,17 @@ T_DECL(chkstk, "chkstk",
        call_chkstk(1 << 16);
        T_PASS("calling with 1 << 16");
 
        call_chkstk(1 << 16);
        T_PASS("calling with 1 << 16");
 
-       signal(TRAPSIG, got_signal);
+       stack_t ss = {
+               .ss_sp    = malloc(MINSIGSTKSZ),
+               .ss_size  = MINSIGSTKSZ,
+       };
+       T_ASSERT_POSIX_SUCCESS(sigaltstack(&ss, NULL), "sigaltstack");
+
+       struct sigaction sa = {
+               .sa_handler = got_signal,
+               .sa_flags = SA_ONSTACK,
+       };
+       T_ASSERT_POSIX_SUCCESS(sigaction(SIGSEGV, &sa, NULL), "sigaction");
 
        call_chkstk(1 << 24);
        T_FAIL("should have crashed");
 
        call_chkstk(1 << 24);
        T_FAIL("should have crashed");
index 3a52747a7bb396ce01aa84d525d673694443f165..2c4780ad94272064554790babb46d4f150518528 100644 (file)
@@ -3,7 +3,11 @@
 #include <stdlib.h>
 #include "darwintest_defaults.h"
 
 #include <stdlib.h>
 #include "darwintest_defaults.h"
 
+#if defined(__arm64__)
+#define PTHREAD_T_OFFSET (12*1024)
+#else
 #define PTHREAD_T_OFFSET (0)
 #define PTHREAD_T_OFFSET (0)
+#endif
 
 static void *
 function(void *arg)
 
 static void *
 function(void *arg)
index 685b494e58c4271208922b897a1966e90561136c..cbe1b844e5c494386a91b1e83e57a9b56b47509c 100644 (file)
@@ -1,4 +1,7 @@
 #!/bin/bash -e
 #!/bin/bash -e
+
+if [ "${DRIVERKIT}" = 1 ]; then exit 0; fi
+
 # install kdebug trace files based on the input file
 INPUT=${SCRIPT_INPUT_FILE_0}
 OUTPUT=${SCRIPT_OUTPUT_FILE_0}
 # install kdebug trace files based on the input file
 INPUT=${SCRIPT_INPUT_FILE_0}
 OUTPUT=${SCRIPT_OUTPUT_FILE_0}
index 9501f969e6bd98298022414bb311804ac367b7ed..ca2d3314fba78109271b462df7730eb34b7ff8f3 100644 (file)
@@ -16,3 +16,9 @@ for variant in $BUILD_VARIANTS; do
 
        ln -sf init.py $DWARF_DSYM_FOLDER_PATH/$DWARF_DSYM_FILE_NAME/Contents/Resources/Python/$EXECUTABLE_NAME$SUFFIX.py
 done
 
        ln -sf init.py $DWARF_DSYM_FOLDER_PATH/$DWARF_DSYM_FILE_NAME/Contents/Resources/Python/$EXECUTABLE_NAME$SUFFIX.py
 done
+
+if test "$PLATFORM_NAME" != macosx; then
+    mkdir -p $DSTROOT/AppleInternal/KextObjects/Python/$MODULE_NAME || true
+    rsync -aq $SRCROOT/lldbmacros/* $DSTROOT/AppleInternal/KextObjects/Python/$MODULE_NAME
+    ln -sf init.py $DSTROOT/AppleInternal/KextObjects/Python/$MODULE_NAME/$EXECUTABLE_NAME.py
+fi
index 26a220587ed60852c546c809395c519777505a08..b8da6deaf7a0446f7c1d2ad83ca7317441f0e7ff 100644 (file)
@@ -23,6 +23,7 @@
 
 if [ "$ACTION" = installhdrs ]; then exit 0; fi
 if [ "${RC_ProjectName%_Sim}" != "${RC_ProjectName}" ]; then exit 0; fi
 
 if [ "$ACTION" = installhdrs ]; then exit 0; fi
 if [ "${RC_ProjectName%_Sim}" != "${RC_ProjectName}" ]; then exit 0; fi
+if [ "${DRIVERKIT}" = 1 ]; then exit 0; fi
 
 set -x
 set -e
 
 set -x
 set -e
index cc4fb2c0aa0e084251bb6554ad0b448ecb0b4e59..e2b10589ee6e7bca943b7887377ef5386e90e42d 100644 (file)
@@ -27,6 +27,8 @@ if [ "$ACTION" = build ]; then exit 0; fi
 # Symlink old header locations.
 #
 
 # Symlink old header locations.
 #
 
+DSTROOT="${DSTROOT}/${SDK_INSTALL_HEADERS_ROOT}"
+
 ln -sf "pthread/pthread.h" "$DSTROOT/usr/include/pthread.h"
 ln -sf "pthread/pthread_impl.h" "$DSTROOT/usr/include/pthread_impl.h"
 ln -sf "pthread/pthread_spis.h" "$DSTROOT/usr/include/pthread_spis.h"
 ln -sf "pthread/pthread.h" "$DSTROOT/usr/include/pthread.h"
 ln -sf "pthread/pthread_impl.h" "$DSTROOT/usr/include/pthread_impl.h"
 ln -sf "pthread/pthread_spis.h" "$DSTROOT/usr/include/pthread_spis.h"
index ca631d1d4bc296cc09741935bc8182127d52f425..a5b4eba646a5fe9334cb8a184e6f92f4fc0baf7b 100644 (file)
@@ -25,6 +25,8 @@ set -e
 
 if [ "$ACTION" = build ]; then exit 0; fi
 
 
 if [ "$ACTION" = build ]; then exit 0; fi
 
+DSTROOT="${DSTROOT}/${SDK_INSTALL_HEADERS_ROOT}"
+
 DESTDIR="$DSTROOT/usr/include/sys"
 mkdir -p "$DESTDIR"
 for X in \
 DESTDIR="$DSTROOT/usr/include/sys"
 mkdir -p "$DESTDIR"
 for X in \
index 84e90796bddc820d2695bfef0642ac03a1429923..c28a73014dd8b43a41b9960338a1038d39226183 100644 (file)
@@ -24,7 +24,7 @@ INFOPLIST_FILE = kern/pthread-Info.plist
 ALWAYS_SEARCH_USER_PATHS = NO
 SRCROOT_SEARCH_PATHS = $(SRCROOT) $(SRCROOT)/pthread $(SRCROOT)/private
 HEADER_SEARCH_PATHS = $(SDKROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders $(SDKROOT)/System/Library/Frameworks/Kernel.framework/Headers $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders $(SDKROOT)/System/Library/Frameworks/System.framework/Headers $(SRCROOT_SEARCH_PATHS)
 ALWAYS_SEARCH_USER_PATHS = NO
 SRCROOT_SEARCH_PATHS = $(SRCROOT) $(SRCROOT)/pthread $(SRCROOT)/private
 HEADER_SEARCH_PATHS = $(SDKROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders $(SDKROOT)/System/Library/Frameworks/Kernel.framework/Headers $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders $(SDKROOT)/System/Library/Frameworks/System.framework/Headers $(SRCROOT_SEARCH_PATHS)
-GCC_C_LANGUAGE_STANDARD = gnu99
+GCC_C_LANGUAGE_STANDARD = gnu11
 CLANG_CXX_LANGUAGE_STANDARD = gnu++0x
 CLANG_CXX_LIBRARY = libc++
 GCC_PRECOMPILE_PREFIX_HEADER = YES
 CLANG_CXX_LANGUAGE_STANDARD = gnu++0x
 CLANG_CXX_LIBRARY = libc++
 GCC_PRECOMPILE_PREFIX_HEADER = YES
@@ -32,7 +32,7 @@ CODE_SIGN_IDENTITY = -
 DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
 
 GCC_OPTIMIZATION_LEVEL_normal = s
 DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
 
 GCC_OPTIMIZATION_LEVEL_normal = s
-GCC_OPTIMIZATION_LEVEL_development = 0
+GCC_OPTIMIZATION_LEVEL_development = s
 GCC_OPTIMIZATION_LEVEL = $(GCC_OPTIMIZATION_LEVEL_$(PTHREAD_VARIANT))
 
 DEAD_CODE_STRIPPING = NO
 GCC_OPTIMIZATION_LEVEL = $(GCC_OPTIMIZATION_LEVEL_$(PTHREAD_VARIANT))
 
 DEAD_CODE_STRIPPING = NO
index 2a8f66e7b9a72ab0e9a68cd65d1649825fc77a82..45990a804b59829688bbf4db1cca14f828b38f0b 100644 (file)
@@ -17,7 +17,6 @@ _exitf
 
 # int-sized
 ___is_threaded
 
 # int-sized
 ___is_threaded
-___libdispatch_offset
 ___pthread_supported_features
 ___pthread_tsd_lock
 ___pthread_tsd_max
 ___pthread_supported_features
 ___pthread_tsd_lock
 ___pthread_tsd_max
index 1dedcaa5a2353f880edeef01161f7aff885d34e0..9094c6dfe61f8adeb59335ffe714f75b72f77247 100644 (file)
@@ -4,15 +4,26 @@ SDKROOT = macosx.internal
 SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator
 BUILD_VARIANTS = normal debug
 
 SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator
 BUILD_VARIANTS = normal debug
 
-INSTALL_PATH = /usr/lib/system
+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
 EXECUTABLE_PREFIX = lib
 PRODUCT_NAME = system_pthread
 EXECUTABLE_PREFIX = lib
 PRODUCT_NAME = system_pthread
-PUBLIC_HEADERS_FOLDER_PATH = /usr/include/pthread
-PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/pthread
+PUBLIC_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/include/pthread
+PRIVATE_HEADERS_FOLDER_PATH = $(SDK_INSTALL_HEADERS_ROOT)/usr/local/include/pthread
 
 SRCROOT_SEARCH_PATHS = $(SRCROOT) $(SRCROOT)/private $(SRCROOT)/os $(SRCROOT)/src/resolver
 
 SRCROOT_SEARCH_PATHS = $(SRCROOT) $(SRCROOT)/private $(SRCROOT)/os $(SRCROOT)/src/resolver
-SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
-HEADER_SEARCH_PATHS = $($(PRODUCT_NAME)_SEARCH_PATHS) $(SRCROOT_SEARCH_PATHS) $(SYSTEM_FRAMEWORK_HEADERS) $(SDKROOT)/usr/local/include $(inherited)
+SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
+HEADER_SEARCH_PATHS = $($(PRODUCT_NAME)_SEARCH_PATHS) $(SRCROOT_SEARCH_PATHS) $(inherited)
+SYSTEM_HEADER_SEARCH_PATHS = $(SYSTEM_FRAMEWORK_HEADERS) $(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
 INSTALLHDRS_SCRIPT_PHASE = YES
 ALWAYS_SEARCH_USER_PATHS = YES
 USE_HEADERMAP = NO
 INSTALLHDRS_SCRIPT_PHASE = YES
 ALWAYS_SEARCH_USER_PATHS = YES
 USE_HEADERMAP = NO
@@ -61,7 +72,7 @@ BASE_PREPROCESSOR_MACROS = __LIBC__ __DARWIN_UNIX03=1 __DARWIN_64_BIT_INO_T=1 __
 GCC_PREPROCESSOR_DEFINITIONS = $(BASE_PREPROCESSOR_MACROS) $(PLATFORM_PREPROCESSOR_DEFINITIONS)
 
 // TODO: Remove -fstack-protector on _debug when it is moved to libplatform
 GCC_PREPROCESSOR_DEFINITIONS = $(BASE_PREPROCESSOR_MACROS) $(PLATFORM_PREPROCESSOR_DEFINITIONS)
 
 // TODO: Remove -fstack-protector on _debug when it is moved to libplatform
-OTHER_CFLAGS = -fno-stack-protector -fno-builtin $(PLATFORM_CFLAGS) $($(PRODUCT_NAME)_CFLAGS)
+OTHER_CFLAGS = -fno-stack-protector -fno-stack-check -fno-builtin $(PLATFORM_CFLAGS) $($(PRODUCT_NAME)_CFLAGS)
 OTHER_CFLAGS_normal = -momit-leaf-frame-pointer
 OTHER_CFLAGS_debug = -fno-inline -O0 -DDEBUG=1
 
 OTHER_CFLAGS_normal = -momit-leaf-frame-pointer
 OTHER_CFLAGS_debug = -fno-inline -O0 -DDEBUG=1
 
@@ -70,11 +81,15 @@ DYLIB_CURRENT_VERSION = $(RC_ProjectSourceVersion)
 DYLIB_COMPATIBILITY_VERSION = 1
 DIRTY_LDFLAGS = -Wl,-dirty_data_list,$(SRCROOT)/xcodescripts/pthread.dirty
 DIRTY_LDFLAGS[sdk=macos*] =
 DYLIB_COMPATIBILITY_VERSION = 1
 DIRTY_LDFLAGS = -Wl,-dirty_data_list,$(SRCROOT)/xcodescripts/pthread.dirty
 DIRTY_LDFLAGS[sdk=macos*] =
-DYLIB_LDFLAGS = -Wl,-alias_list,$(SRCROOT)/xcodescripts/pthread.aliases -Wl,-umbrella,System -L/usr/lib/system -lsystem_kernel -lsystem_platform -ldyld -lcompiler_rt
-OTHER_LDFLAGS = $(DYLIB_LDFLAGS) $(DIRTY_LDFLAGS) $(CR_LDFLAGS) $(PLATFORM_LDFLAGS)
+DYLIB_LDFLAGS = -Wl,-alias_list,$(SRCROOT)/xcodescripts/pthread.aliases -Wl,-umbrella,System -L$(SDK_INSTALL_ROOT)/usr/lib/system -lsystem_kernel -lsystem_platform -ldyld -lcompiler_rt
+OTHER_LDFLAGS = $(DYLIB_LDFLAGS) $(DIRTY_LDFLAGS) $(CR_LDFLAGS) $(PLATFORM_LDFLAGS) $(SIMULATOR_LDFLAGS)
+
+SIMULATOR_LDFLAGS =
+SIMULATOR_LDFLAGS[sdk=macosx*] = -Wl,-simulator_support
+IS_ZIPPERED = YES
+
 
 // Simulator build rules
 EXCLUDED_SOURCE_FILE_NAMES[sdk=iphonesimulator*] = *.c *.s
 SKIP_INSTALL[sdk=iphonesimulator*] = YES
 OTHER_LDFLAGS[sdk=iphonesimulator*] =
 
 // Simulator build rules
 EXCLUDED_SOURCE_FILE_NAMES[sdk=iphonesimulator*] = *.c *.s
 SKIP_INSTALL[sdk=iphonesimulator*] = YES
 OTHER_LDFLAGS[sdk=iphonesimulator*] =
-