JL_DLLEXPORT int jl_dlsym(void *handle, const char *symbol, void ** value, int throw_err) { int symbol_found = 0; /* First, get the symbol value */ #ifdef _OS_WINDOWS_ *value = GetProcAddress((HMODULE) handle, symbol); #else dlerror(); /* Reset error status. */ *value = dlsym(handle, symbol); #endif /* Next, check for errors. On Windows, a NULL pointer means the symbol * was not found. On everything else, we can have NULL symbols, so we check * for non-NULL returns from dlerror(). Note that we unconditionally call * jl_dlerror() on POSIX systems, but on Windows systems we only call it * when we have been returned a NULL symbol.*/ const char * err = NULL; #ifdef _OS_WINDOWS_ symbol_found = *value != NULL; #else err = jl_dlerror(); symbol_found = err == NULL; #endif if (!symbol_found && throw_err) { #ifdef _OS_WINDOWS_ err = jl_dlerror(); #endif jl_errorf("could not load symbol \"%s\":\n%s", symbol, err); } return symbol_found; }
JL_DLLEXPORT void *jl_dlsym(void *handle, const char *symbol) { void *ptr = jl_dlsym_e(handle, symbol); if (!ptr) jl_dlerror("could not load symbol \"%s\":\n%s", symbol); return ptr; }
JL_DLLEXPORT void *jl_load_dynamic_library(const char *modname, unsigned flags, int throw_err) { char path[PATHBUF]; int i; uv_stat_t stbuf; void *handle; int abspath; // number of extensions to try — if modname already ends with the // standard extension, then we don't try adding additional extensions int n_extensions = endswith_extension(modname) ? 1 : N_EXTENSIONS; /* this branch returns handle of libjulia */ if (modname == NULL) { #ifdef _OS_WINDOWS_ if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCWSTR)(uintptr_t)(&jl_load_dynamic_library), (HMODULE*)&handle)) { jl_error("could not load base module"); } #else Dl_info info; if (!dladdr((void*)(uintptr_t)&jl_load_dynamic_library, &info) || !info.dli_fname) jl_error("could not load base module"); handle = dlopen(info.dli_fname, RTLD_NOW); #endif goto done; } abspath = isabspath(modname); /* this branch permutes all base paths in DL_LOAD_PATH with all extensions note: skip when !jl_base_module to avoid UndefVarError(:DL_LOAD_PATH), and also skip for absolute paths */ if (!abspath && jl_base_module != NULL) { jl_array_t *DL_LOAD_PATH = (jl_array_t*)jl_get_global(jl_base_module, jl_symbol("DL_LOAD_PATH")); if (DL_LOAD_PATH != NULL) { size_t j; for (j = 0; j < jl_array_len(DL_LOAD_PATH); j++) { char *dl_path = jl_string_data(jl_array_ptr_data(DL_LOAD_PATH)[j]); size_t len = strlen(dl_path); if (len == 0) continue; for (i=0; i < n_extensions; i++) { const char *ext = extensions[i]; path[0] = '\0'; if (dl_path[len-1] == PATHSEPSTRING[0]) snprintf(path, PATHBUF, "%s%s%s", dl_path, modname, ext); else snprintf(path, PATHBUF, "%s" PATHSEPSTRING "%s%s", dl_path, modname, ext); handle = jl_dlopen(path, flags); if (handle) goto done; // bail out and show the error if file actually exists if (jl_stat(path, (char*)&stbuf) == 0) goto notfound; } } } } // now fall back and look in default library paths, for all extensions for(i=0; i < n_extensions; i++) { const char *ext = extensions[i]; path[0] = '\0'; snprintf(path, PATHBUF, "%s%s", modname, ext); handle = jl_dlopen(path, flags); if (handle) goto done; } notfound: if (throw_err) { const char * reason = jl_dlerror(); jl_errorf("could not load library \"%s\"\n%s", modname, reason); } return NULL; done: return handle; }
static void *jl_load_dynamic_library_(const char *modname, unsigned flags, int throw_err) { char *ext; char path[PATHBUF]; int i; uv_stat_t stbuf; void *handle; /* this branch returns handle of libjulia */ if (modname == NULL) { #ifdef _OS_WINDOWS_ if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCWSTR)(&jl_load_dynamic_library), (HMODULE*)&handle)) { jl_error("could not load base module"); } #else handle = dlopen(NULL, RTLD_NOW); #endif goto done; } /* this branch shortcuts absolute paths */ #ifdef _OS_WINDOWS_ else if (modname[1] == ':') { #else else if (modname[0] == '/') { #endif handle = jl_dlopen(modname, flags); if (handle) goto done; // bail out and show the error if file actually exists if (jl_stat(modname, (char*)&stbuf) == 0) goto notfound; } /* this branch permutes all base paths in DL_LOAD_PATH with all extensions note: skip when !jl_base_module to avoid UndefVarError(:DL_LOAD_PATH) */ else if (jl_base_module != NULL) { jl_array_t *DL_LOAD_PATH = (jl_array_t*)jl_get_global(jl_base_module, jl_symbol("DL_LOAD_PATH")); if (DL_LOAD_PATH != NULL) { size_t j; for (j = 0; j < jl_array_len(DL_LOAD_PATH); j++) { char *dl_path = jl_string_data(jl_cell_data(DL_LOAD_PATH)[j]); size_t len = strlen(dl_path); if (len == 0) continue; for(i=0; i < N_EXTENSIONS; i++) { ext = extensions[i]; path[0] = '\0'; handle = NULL; if (dl_path[len-1] == PATHSEPSTRING[0]) snprintf(path, PATHBUF, "%s%s%s", dl_path, modname, ext); else snprintf(path, PATHBUF, "%s" PATHSEPSTRING "%s%s", dl_path, modname, ext); handle = jl_dlopen(path, flags); if (handle) goto done; // bail out and show the error if file actually exists if (jl_stat(path, (char*)&stbuf) == 0) goto notfound; } } } } // now fall back and look in default library paths, for all extensions for(i=0; i < N_EXTENSIONS; i++) { ext = extensions[i]; path[0] = '\0'; handle = NULL; snprintf(path, PATHBUF, "%s%s", modname, ext); handle = jl_dlopen(path, flags); if (handle) goto done; } #if defined(__linux__) || defined(__FreeBSD__) // check map of versioned libs from "libX" to full soname "libX.so.ver" { const char *soname = jl_lookup_soname(modname, strlen(modname)); if (soname) { handle = jl_dlopen(soname, flags); if (handle) goto done; } } #endif notfound: if (throw_err) jl_dlerror("could not load library \"%s\"\n%s", modname); return NULL; done: return handle; } JL_DLLEXPORT void *jl_load_dynamic_library_e(const char *modname, unsigned flags) { return jl_load_dynamic_library_(modname, flags, 0); } JL_DLLEXPORT void *jl_load_dynamic_library(const char *modname, unsigned flags) { return jl_load_dynamic_library_(modname, flags, 1); } JL_DLLEXPORT void *jl_dlsym_e(void *handle, const char *symbol) { #ifdef _OS_WINDOWS_ void *ptr = GetProcAddress((HMODULE) handle, symbol); #else dlerror(); /* Reset error status. */ void *ptr = dlsym(handle, symbol); #endif return ptr; }