diff options
Diffstat (limited to 'lib/darwin/inject-asm-raw.c')
-rw-r--r-- | lib/darwin/inject-asm-raw.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/lib/darwin/inject-asm-raw.c b/lib/darwin/inject-asm-raw.c index 3b0f1ce..9b272e7 100644 --- a/lib/darwin/inject-asm-raw.c +++ b/lib/darwin/inject-asm-raw.c @@ -8,32 +8,37 @@ struct baton { int (*pthread_create)(int *, void *, void *(*)(void *), void *); - void (*dlopen)(const char *, int); + void *(*dlopen)(const char *, int); + void *(*dlsym)(void *, const char *); + int (*munmap)(void *, long); const char *path; - long done; + /* bsd_thread_func uses this to wait for entry to go away */ + long sem_port; + long nshuttle; + char shuttle[0]; }; -struct baton2 { - void (*dlopen)(const char *, int); - const char *path; - int port; -}; -static void *bsd_thread_func(void *); +static int bsd_thread_func(void *); #if defined(__i386__) __attribute__((fastcall)) #endif -/* xxx need to change this to have host allocate two pages - way easier */ void entry(struct baton *baton) { int pt; - baton->pthread_create(&pt, 0, bsd_thread_func, baton); - unsigned long ptr = (unsigned long) baton & ~(_PAGE_SIZE - 1); - while (!baton->done) - manual_syscall(-62 /*clock_sleep_trap */, 0, 1, 0, 8000 /*ns*/, -1); - manual_syscall(361 /*bsdthread_terminate*/, ptr, 0x2000, 0, 0, 0); + baton->pthread_create(&pt, 0, (void *) bsd_thread_func, baton); + manual_syscall(361 /* bsdthread_terminate */, 0, 0, 0, baton->sem_port); ((void (*)()) 0xbad)(); } -static void *bsd_thread_func(void *arg) { +static int bsd_thread_func(void *arg) { struct baton *baton = arg; - baton->dlopen(baton->path, 0); - baton->done = 1; - return 0; + void *r = baton->dlopen(baton->path, 0); + if (r) { + __attribute__((section("__TEXT,__text"))) + static char name[] = "substitute_init"; + void (*init)(void *, unsigned long) = baton->dlsym(r, name); + if (init) + init(baton->shuttle, baton->nshuttle); + + } + manual_syscall(-36 /* semaphore_wait_trap */, baton->sem_port, 0, 0, 0); + unsigned long ptr = (unsigned long) baton & ~(_PAGE_SIZE - 1); + return baton->munmap((void *) ptr, 0x2000); } |