+ $bzero(&self, sizeof(self));
+
+ const mach_header_xx *pthread(NULL);
+ if (pthread == NULL)
+ pthread = Library(baton, "/usr/lib/system/libsystem_pthread.dylib");
+ if (pthread == NULL)
+ pthread = Library(baton, "/usr/lib/system/libsystem_c.dylib");
+ if (pthread == NULL)
+ pthread = Library(baton, "/usr/lib/libSystem.B.dylib");
+
+ void (*$__pthread_set_self)(pthread_t);
+ cyset($__pthread_set_self, "___pthread_set_self", pthread);
+
+ self.tsd[0] = &self;
+ $__pthread_set_self(&self);
+
+ int (*$pthread_attr_init)(pthread_attr_t *);
+ cyset($pthread_attr_init, "_pthread_attr_init", pthread);
+
+#if 0
+ pthread_attr_t attr;
+ $pthread_attr_init(&attr);
+
+ int (*$pthread_attr_setdetachstate)(pthread_attr_t *, int);
+ cyset($pthread_attr_setdetachstate, "_pthread_attr_setdetachstate", pthread);
+
+ $pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+#endif
+
+ int (*$pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
+ cyset($pthread_create, "_pthread_create", pthread);
+
+ pthread_t thread;
+ $pthread_create(&thread, NULL, &Routine, baton);
+
+#if 0
+ int (*$pthread_attr_destroy)(pthread_attr_t *);
+ cyset($pthread_attr_destroy, "_pthread_attr_destroy", pthread);
+
+ $pthread_attr_destroy(&attr);
+#endif
+
+#if defined(__arm__) || defined(__arm64__)
+ uintptr_t tpid;
+#if defined(__arm__)
+ __asm__ ("mrc p15, 0, %0, c13, c0, 3\n" : "=r" (tpid));
+#elif defined(__arm64__)
+ __asm__ ("mrs %0, tpidrro_el0\n" : "=r" (tpid));
+#else
+#error XXX
+#endif
+
+ void **tsd;
+ tsd = reinterpret_cast<void **>(tpid & ~3);
+ if (tsd != NULL)
+ tsd[0] = &self;
+#else
+ _pthread_setspecific_direct(0, &self);
+#endif
+
+ int (*$pthread_join)(pthread_t, void **);
+ cyset($pthread_join, "_pthread_join", pthread);
+
+ void *status;
+ $pthread_join(thread, &status);
+
+ const mach_header_xx *kernel(NULL);
+ if (kernel == NULL)
+ kernel = Library(baton, "/usr/lib/system/libsystem_kernel.dylib");
+ if (kernel == NULL)
+ kernel = Library(baton, "/usr/lib/libSystem.B.dylib");
+
+ mach_port_t (*$mach_thread_self)();
+ cyset($mach_thread_self, "_mach_thread_self", kernel);
+
+ kern_return_t (*$thread_terminate)(thread_act_t);
+ cyset($thread_terminate, "_thread_terminate", kernel);
+
+ $thread_terminate($mach_thread_self());