From 9489e64ccfeb85f22896add64536138e9fe4d0f0 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Mon, 21 Dec 2020 17:44:53 -0800 Subject: [PATCH] Adapt Windows `cglobal()` search for `libjulia-internal` On Windows, we have a special list of libraries that we search for default symbol resolution. Now that we have symbols defined in `libjulia` and then imported by `libjulia-internal`, we need to make certain that we search `libjulia-internal` first (so that we find non-trampoline functions first) and then `libjulia` (so that we do in fact eventually find the symbols at all). --- src/ccall.cpp | 6 +++--- src/codegen.cpp | 4 ++-- src/dlload.c | 10 ++++++---- src/init.c | 8 ++++++-- src/julia.h | 2 +- src/julia_internal.h | 12 +++++++++--- src/runtime_ccall.cpp | 6 ++++-- 7 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/ccall.cpp b/src/ccall.cpp index abc219d3b701f..8ef419d18bf84 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -22,11 +22,11 @@ static bool runtime_sym_gvs(jl_codegen_params_t &emission_context, const char *f GlobalVariable *libptrgv; jl_codegen_params_t::SymMapGV *symMap; #ifdef _OS_WINDOWS_ - if ((intptr_t)f_lib == 1) { + if ((intptr_t)f_lib == (intptr_t)JL_EXE_LIBNAME) { libptrgv = prepare_global_in(M, jlexe_var); symMap = &emission_context.symMapExe; } - else if ((intptr_t)f_lib == 2) { + else if ((intptr_t)f_lib == (intptr_t)JL_LIBJULIA_INTERNAL_DL_LIBNAME) { libptrgv = prepare_global_in(M, jldll_var); symMap = &emission_context.symMapDl; } @@ -1266,7 +1266,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) auto _is_libjulia_func = [&] (uintptr_t ptr, const char *name) { if ((uintptr_t)fptr == ptr) return true; - return (!f_lib || f_lib == JL_DL_LIBNAME) && f_name && !strcmp(f_name, name); + return (!f_lib || f_lib == JL_LIBJULIA_INTERNAL_DL_LIBNAME) && f_name && !strcmp(f_name, name); }; #define is_libjulia_func(name) _is_libjulia_func((uintptr_t)&(name), #name) diff --git a/src/codegen.cpp b/src/codegen.cpp index 94bd794677a11..144c3d8636e95 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -397,7 +397,7 @@ static const auto jlexe_var = new JuliaVariable{ [](LLVMContext &C) { return T_pint8; }, }; static const auto jldll_var = new JuliaVariable{ - "jl_dl_handle", + "jl_libjulia_internal_handle", true, [](LLVMContext &C) { return T_pint8; }, }; @@ -7531,7 +7531,7 @@ static void init_jit_functions(void) add_named_global(jlRTLD_DEFAULT_var, &jl_RTLD_DEFAULT_handle); #ifdef _OS_WINDOWS_ add_named_global(jlexe_var, &jl_exe_handle); - add_named_global(jldll_var, &jl_dl_handle); + add_named_global(jldll_var, &jl_libjulia_internal_handle); #endif global_jlvalue_to_llvm(new JuliaVariable{"jl_true", true, get_pjlvalue}, &jl_true); global_jlvalue_to_llvm(new JuliaVariable{"jl_false", true, get_pjlvalue}, &jl_false); diff --git a/src/dlload.c b/src/dlload.c index f696eabc4382d..0765f0e14c07c 100644 --- a/src/dlload.c +++ b/src/dlload.c @@ -308,8 +308,10 @@ const char *jl_dlfind_win32(const char *f_name) void * dummy; if (jl_dlsym(jl_exe_handle, f_name, &dummy, 0)) return JL_EXE_LIBNAME; - if (jl_dlsym(jl_dl_handle, f_name, &dummy, 0)) - return JL_DL_LIBNAME; + if (jl_dlsym(jl_libjulia_internal_handle, f_name, &dummy, 0)) + return JL_LIBJULIA_INTERNAL_DL_LIBNAME; + if (jl_dlsym(jl_libjulia_handle, f_name, &dummy, 0)) + return JL_LIBJULIA_DL_LIBNAME; if (jl_dlsym(jl_kernel32_handle, f_name, &dummy, 0)) return "kernel32"; if (jl_dlsym(jl_ntdll_handle, f_name, &dummy, 0)) @@ -334,8 +336,8 @@ const char *jl_dlfind_win32(const char *f_name) // explicit is preferred over implicit return NULL; // oops, we didn't find it. NULL defaults to searching jl_RTLD_DEFAULT_handle, - // which defaults to jl_dl_handle, where we won't find it, and will throw the - // appropriate error. + // which defaults to jl_libjulia_internal_handle, where we won't find it, and + // will throw the appropriate error. } #endif diff --git a/src/init.c b/src/init.c index e69c43837787d..a421578239680 100644 --- a/src/init.c +++ b/src/init.c @@ -293,7 +293,8 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode) static void post_boot_hooks(void); -JL_DLLEXPORT void *jl_dl_handle; +JL_DLLEXPORT void *jl_libjulia_internal_handle; +JL_DLLEXPORT void *jl_libjulia_handle; void *jl_RTLD_DEFAULT_handle; JL_DLLEXPORT void *jl_exe_handle; #ifdef _OS_WINDOWS_ @@ -657,7 +658,10 @@ void _julia_init(JL_IMAGE_SEARCH rel) jl_prep_sanitizers(); void *stack_lo, *stack_hi; jl_init_stack_limits(1, &stack_lo, &stack_hi); - jl_dl_handle = jl_load_dynamic_library(NULL, JL_RTLD_DEFAULT, 1); + + // Load libjulia-internal (which contains this function), and libjulia, explicitly. + jl_libjulia_internal_handle = jl_load_dynamic_library(NULL, JL_RTLD_DEFAULT, 1); + jl_libjulia_handle = jl_load_dynamic_library(JL_LIBJULIA_DL_LIBNAME, JL_RTLD_DEFAULT, 1); #ifdef _OS_WINDOWS_ jl_ntdll_handle = jl_dlopen("ntdll.dll", 0); // bypass julia's pathchecking for system dlls jl_kernel32_handle = jl_dlopen("kernel32.dll", 0); diff --git a/src/julia.h b/src/julia.h index f6518c497acf2..c16f9000fd89e 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1515,7 +1515,7 @@ JL_DLLEXPORT int jl_is_debugbuild(void) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_sym_t *jl_get_UNAME(void) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_sym_t *jl_get_ARCH(void) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_value_t *jl_get_libllvm(void) JL_NOTSAFEPOINT; -extern JL_DLLEXPORT int jl_n_threads; +extern JL_DLLIMPORT int jl_n_threads; // environment entries JL_DLLEXPORT jl_value_t *jl_environ(int i); diff --git a/src/julia_internal.h b/src/julia_internal.h index 8f8c666b74aec..416fedf6dbbf6 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -990,7 +990,8 @@ STATIC_INLINE uint64_t cong(uint64_t max, uint64_t unbias, uint64_t *seed) } // libuv stuff: -JL_DLLEXPORT extern void *jl_dl_handle; +JL_DLLEXPORT extern void *jl_libjulia_handle; +JL_DLLEXPORT extern void *jl_libjulia_internal_handle; JL_DLLEXPORT extern void *jl_RTLD_DEFAULT_handle; #if defined(_OS_WINDOWS_) JL_DLLEXPORT extern void *jl_exe_handle; @@ -1012,8 +1013,13 @@ JL_DLLEXPORT jl_value_t *jl_get_cfunction_trampoline( // Windows only -#define JL_EXE_LIBNAME ((const char*)1) -#define JL_DL_LIBNAME ((const char*)2) +#define JL_EXE_LIBNAME ((const char*)1) +#define JL_LIBJULIA_INTERNAL_DL_LIBNAME ((const char*)2) +#if defined(JL_DEBUG_BUILD) +#define JL_LIBJULIA_DL_LIBNAME "libjulia-debug" +#else +#define JL_LIBJULIA_DL_LIBNAME "libjulia" +#endif const char *jl_dlfind_win32(const char *name); // libuv wrappers: diff --git a/src/runtime_ccall.cpp b/src/runtime_ccall.cpp index b9b3ed4dea41a..0dd727749f30e 100644 --- a/src/runtime_ccall.cpp +++ b/src/runtime_ccall.cpp @@ -33,8 +33,10 @@ void *jl_get_library_(const char *f_lib, int throw_err) JL_NOTSAFEPOINT #ifdef _OS_WINDOWS_ if (f_lib == JL_EXE_LIBNAME) return jl_exe_handle; - if (f_lib == JL_DL_LIBNAME) - return jl_dl_handle; + if (f_lib == JL_LIBJULIA_INTERNAL_DL_LIBNAME) + return jl_libjulia_internal_handle; + if (f_lib == JL_LIBJULIA_DL_LIBNAME) + return jl_libjulia_handle; #endif if (f_lib == NULL) return jl_RTLD_DEFAULT_handle;