Skip to content

Commit

Permalink
Change Windows CRT func to be considered as libjulia func (JuliaLang#…
Browse files Browse the repository at this point in the history
…39636)

This prefers crtdll over ntdll.
This supports the specialization of `memcpy` ccall on Windows.
  • Loading branch information
kimikage authored and ElOceanografo committed May 4, 2021
1 parent 4d18894 commit 96632d1
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 16 deletions.
19 changes: 18 additions & 1 deletion src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <llvm/Bitcode/BitcodeReader.h>
#include <llvm/Linker/Linker.h>

#ifdef _OS_WINDOWS_
extern const char jl_crtdll_basename[];
#endif

// somewhat unusual variable, in that aotcompile wants to get the address of this for a sanity check
GlobalVariable *jl_emit_RTLD_DEFAULT_var(Module *M)
{
Expand Down Expand Up @@ -1266,7 +1270,20 @@ 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_LIBJULIA_INTERNAL_DL_LIBNAME) && f_name && !strcmp(f_name, name);
if (f_lib) {
#ifdef _OS_WINDOWS_
if ((f_lib == JL_EXE_LIBNAME) || // preventing invalid pointer access
(f_lib == JL_LIBJULIA_INTERNAL_DL_LIBNAME) ||
(!strcmp(f_lib, jl_crtdll_basename))) {
// libjulia-like
}
else
return false;
#else
return false;
#endif
}
return f_name && !strcmp(f_name, name);
};
#define is_libjulia_func(name) _is_libjulia_func((uintptr_t)&(name), #name)

Expand Down
31 changes: 21 additions & 10 deletions src/dlload.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,25 @@ static int endswith_extension(const char *path) JL_NOTSAFEPOINT
return 0;
}

#ifdef _OS_WINDOWS_
#ifdef _MSC_VER
#if (_MSC_VER >= 1930) || (_MSC_VER < 1800)
#error This version of MSVC has not been tested.
#elif _MSC_VER >= 1900 // VC++ 2015 / 2017 / 2019
#define CRTDLL_BASENAME "vcruntime140"
#elif _MSC_VER >= 1800 // VC++ 2013
#define CRTDLL_BASENAME "msvcr120"
#endif
#else
#define CRTDLL_BASENAME "msvcrt"
#endif

const char jl_crtdll_basename[] = CRTDLL_BASENAME;
const char jl_crtdll_name[] = CRTDLL_BASENAME ".dll";

#undef CRTDLL_BASENAME
#endif

#define PATHBUF 4096

#define JL_RTLD(flags, FLAG) (flags & JL_RTLD_ ## FLAG ? RTLD_ ## FLAG : 0)
Expand Down Expand Up @@ -314,18 +333,10 @@ const char *jl_dlfind_win32(const char *f_name)
return JL_LIBJULIA_DL_LIBNAME;
if (jl_dlsym(jl_kernel32_handle, f_name, &dummy, 0))
return "kernel32";
if (jl_dlsym(jl_crtdll_handle, f_name, &dummy, 0)) // Prefer crtdll over ntdll
return jl_crtdll_basename;
if (jl_dlsym(jl_ntdll_handle, f_name, &dummy, 0))
return "ntdll";
if (jl_dlsym(jl_crtdll_handle, f_name, &dummy, 0))
#if defined(_MSC_VER)
#if _MSC_VER == 1800
return "msvcr120";
#else
#error This version of MSVC has not been tested.
#endif
#else
return "msvcrt";
#endif
if (jl_dlsym(jl_winsock_handle, f_name, &dummy, 0))
return "ws2_32";
// additional common libraries (libc?) could be added here, but in general,
Expand Down
7 changes: 2 additions & 5 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ void *jl_ntdll_handle;
void *jl_kernel32_handle;
void *jl_crtdll_handle;
void *jl_winsock_handle;
extern const char jl_crtdll_name[];
#endif

uv_loop_t *jl_io_loop;
Expand Down Expand Up @@ -665,11 +666,7 @@ void _julia_init(JL_IMAGE_SEARCH rel)
#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);
#if defined(_MSC_VER) && _MSC_VER == 1800
jl_crtdll_handle = jl_dlopen("msvcr120.dll", 0);
#else
jl_crtdll_handle = jl_dlopen("msvcrt.dll", 0);
#endif
jl_crtdll_handle = jl_dlopen(jl_crtdll_name, 0);
jl_winsock_handle = jl_dlopen("ws2_32.dll", 0);
jl_exe_handle = GetModuleHandleA(NULL);
JL_MUTEX_INIT(&jl_in_stackwalk);
Expand Down
13 changes: 13 additions & 0 deletions test/ccall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,19 @@ let
@test arr[1] == '0'
end

# issue #38751
let
function f38751!(dest::Vector{UInt8}, src::Vector{UInt8}, n::UInt)
d, s = pointer(dest), pointer(src)
GC.@preserve dest src ccall(:memcpy, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Csize_t), d, s, n)
return dest
end
dest = zeros(UInt8, 8)
@test f38751!(dest, collect(0x1:0x8), UInt(8)) == 0x1:0x8
llvm = sprint(code_llvm, f38751!, (Vector{UInt8}, Vector{UInt8}, UInt))
@test !occursin("call void inttoptr", llvm)
end

# issue #34061
let o_file = tempname(), err = Base.PipeEndpoint()
run(pipeline(Cmd(`$(Base.julia_cmd()) --color=no --output-o=$o_file -e '
Expand Down

0 comments on commit 96632d1

Please sign in to comment.