Skip to content

Instantly share code, notes, and snippets.

Last active Jul 23, 2020
What would you like to do?
Fix applications that use JIT on Apple silicon but don't know about pthread_jit_write_protect_np
// The usual: compile with clang libfixjit.c -arch arm64 -arch arm64e -shared -o libfixjit.dylib, add to DYLD_INSERT_LIBRARIES.
#include <errno.h>
#include <pthread.h>
#include <stdatomic.h>
__attribute__((constructor)) static void fix_jit() {
unsigned long long mask;
__asm__ volatile("mrs %0, s3_4_c15_c2_7" : "=r"(mask): :);
__asm__ volatile("msr s3_4_c15_c2_7, %0" : : "r"(mask & 0xfffffffff0ffffff) :);
typedef struct {
void *(*function)();
void *argument;
} pthread_context;
static pthread_context context_arena[4096 /* ought to be enough for anybody */];
static atomic_size_t arena_top = sizeof(context_arena) / sizeof(*context_arena);
static void *fix_jit_trampoline(void *argument) {
pthread_context *context = (pthread_context *)argument;
return context->function(context->argument);
int overriden_pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) {
size_t context;
if ((context = --arena_top)) {
context_arena[context] = (pthread_context) { start_routine, arg };
return pthread_create(thread, attr, fix_jit_trampoline, context_arena + context);
} else {
return EAGAIN;
__attribute__((used, section("__DATA,__interpose"))) static struct {
int (*overriden_pthread_create)();
int (*pthread_create)();
} pthread_create_interpose = {overriden_pthread_create, pthread_create};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment