static int bind_now_close(lt_user_data d, lt_module m) { pa_assert(m); if (dlclose(m) != 0){ lt_dlseterror(LT_ERROR_CANNOT_CLOSE); return 1; } return 0; }
static lt_module bind_now_open(lt_user_data d, const char *fname, lt_dladvise advise) { lt_module m; pa_assert(fname); if (!(m = dlopen(fname, PA_BIND_NOW))) { lt_dlseterror(LT_ERROR_CANNOT_OPEN); return NULL; } return m; }
static lt_ptr bind_now_find_sym(lt_user_data d, lt_module m, const char *symbol) { lt_ptr ptr; pa_assert(m); pa_assert(symbol); if (!(ptr = dlsym(m, symbol))) { lt_dlseterror(LT_ERROR_SYMBOL_NOT_FOUND); return NULL; } return ptr; }
/* A function called through the vtable when a particular module should be unloaded. */ static int vm_close (lt_user_data loader_data, lt_module module) { int errors = 0; if (module != (lt_module) -1) { const mach_header *mh = (const mach_header *) module; int flags = 0; if (mh->magic == LT__MAGIC) { lt_dlseterror (dyld_cannot_close); ++errors; } else { /* Currently, if a module contains c++ static destructors and it is unloaded, we get a segfault in atexit(), due to compiler and dynamic loader differences of opinion, this works around that. */ if ((const struct section *) NULL != getsectbynamefromheader (lt__nsmodule_get_header (module), "__DATA", "__mod_term_func")) { flags |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; } #if defined(__ppc__) flags |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES; #endif if (!NSUnLinkModule (module, flags)) { DYLD__SETERROR (CANNOT_CLOSE); ++errors; } } } return errors; }