Skip to content

Commit

Permalink
Adapt Windows cglobal() search for libjulia-internal
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
staticfloat committed Dec 22, 2020
1 parent 926a3ca commit 9489e64
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 17 deletions.
6 changes: 3 additions & 3 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)

Expand Down
4 changes: 2 additions & 2 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; },
};
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 6 additions & 4 deletions src/dlload.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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

Expand Down
8 changes: 6 additions & 2 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 9 additions & 3 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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:
Expand Down
6 changes: 4 additions & 2 deletions src/runtime_ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)

This comment has been minimized.

Copy link
@vtjnash

vtjnash Dec 22, 2020

Member

this should always compare to false

This comment has been minimized.

Copy link
@staticfloat

staticfloat Dec 22, 2020

Author Member

hmmm, so there's no way for a function from libjulia to show up here? Why not?

This comment has been minimized.

Copy link
@vtjnash

vtjnash Dec 22, 2020

Member

Sure, I'm just pointing out that you're testing one external string pointer against a pointer to a private copy of a string, which should almost always be false

This comment has been minimized.

Copy link
@staticfloat

staticfloat Dec 23, 2020

Author Member

Ah, doy. The rest are integer values, not actual strings.

Would you prefer that we change this to strcmp() or to just drop the comparison here?

This comment has been minimized.

Copy link
@vtjnash

vtjnash Dec 24, 2020

Member

I suppose we'll need it, if we start exporting things from libjulia?

return jl_libjulia_handle;
#endif
if (f_lib == NULL)
return jl_RTLD_DEFAULT_handle;
Expand Down

0 comments on commit 9489e64

Please sign in to comment.