#include #include #include #include #include #include #include "elfcalls.h" #include "threads.h" static void* dlopen_simple(const char* name) { return dlopen(name, RTLD_LAZY); } static void* dlopen_fatal(const char* name) { void* rv = dlopen_simple(name); if (!rv) { fprintf(stderr, "Cannot load %s (ELF): %s\n", name, dlerror()); abort(); } return rv; } static void* dlsym_fatal(void* handle, const char* sym) { void* addr = dlsym(handle, sym); if (!addr) { fprintf(stderr, "Failed to lookup symbol %s (ELF): %s\n", sym, dlerror()); abort(); } return addr; } static int dlclose_fatal(void* handle) { if (dlclose(handle) != 0) { fprintf(stderr, "Cannot dlclose library (ELF): %s\n", dlerror()); abort(); } return 0; } static int get_errno(void) { return errno; } void elfcalls_make(struct elf_calls* calls) { calls->dlopen = dlopen_simple; calls->dlclose = dlclose; calls->dlsym = dlsym; calls->dlerror = dlerror; calls->dlopen_fatal = dlopen_fatal; calls->dlsym_fatal = dlsym_fatal; calls->dlclose_fatal = dlclose_fatal; calls->darling_thread_create = __darling_thread_create; calls->darling_thread_terminate = __darling_thread_terminate; calls->darling_thread_get_stack = __darling_thread_get_stack; calls->get_errno = get_errno; calls->exit = exit; *((void**)&calls->sem_open) = sem_open; *((void**)&calls->sem_wait) = sem_wait; *((void**)&calls->sem_trywait) = sem_trywait; *((void**)&calls->sem_post) = sem_post; *((void**)&calls->sem_close) = sem_close; *((void**)&calls->sem_unlink) = sem_unlink; *((void**)&calls->shm_open) = shm_open; *((void**)&calls->shm_unlink) = shm_unlink; } int main(int argc, const char** argv) { typedef void (*retfunc)(void); struct elf_calls* calls; retfunc ret; // for (int i = 0; i < argc; i++) // printf("arg %d: %s\n", i, argv[i]); calls = (struct elf_calls*) strtoul(argv[1], NULL, 16); ret = (retfunc) strtoul(argv[2], NULL, 16); // puts("before elfcalls_make"); elfcalls_make(calls); // puts("after elfcalls_make"); // printf("Will call %p\n", ret); ret(); __builtin_unreachable(); }