Skip to content

Commit df40b35

Browse files
kimikageKristofferC
authored andcommitted
Change Windows CRT func to be considered as libjulia func (#39636)
This prefers crtdll over ntdll. This supports the specialization of `memcpy` ccall on Windows. (cherry picked from commit 5945f4d)
1 parent 171f7e6 commit df40b35

File tree

4 files changed

+54
-16
lines changed

4 files changed

+54
-16
lines changed

src/ccall.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
#include <llvm/Bitcode/BitcodeReader.h>
66
#include <llvm/Linker/Linker.h>
77

8+
#ifdef _OS_WINDOWS_
9+
extern const char jl_crtdll_basename[];
10+
#endif
11+
812
// somewhat unusual variable, in that aotcompile wants to get the address of this for a sanity check
913
GlobalVariable *jl_emit_RTLD_DEFAULT_var(Module *M)
1014
{
@@ -1266,7 +1270,20 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
12661270
auto _is_libjulia_func = [&] (uintptr_t ptr, const char *name) {
12671271
if ((uintptr_t)fptr == ptr)
12681272
return true;
1269-
return (!f_lib || f_lib == JL_LIBJULIA_INTERNAL_DL_LIBNAME) && f_name && !strcmp(f_name, name);
1273+
if (f_lib) {
1274+
#ifdef _OS_WINDOWS_
1275+
if ((f_lib == JL_EXE_LIBNAME) || // preventing invalid pointer access
1276+
(f_lib == JL_LIBJULIA_INTERNAL_DL_LIBNAME) ||
1277+
(!strcmp(f_lib, jl_crtdll_basename))) {
1278+
// libjulia-like
1279+
}
1280+
else
1281+
return false;
1282+
#else
1283+
return false;
1284+
#endif
1285+
}
1286+
return f_name && !strcmp(f_name, name);
12701287
};
12711288
#define is_libjulia_func(name) _is_libjulia_func((uintptr_t)&(name), #name)
12721289

src/dlload.c

+21-10
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,25 @@ static int endswith_extension(const char *path) JL_NOTSAFEPOINT
5757
return 0;
5858
}
5959

60+
#ifdef _OS_WINDOWS_
61+
#ifdef _MSC_VER
62+
#if (_MSC_VER >= 1930) || (_MSC_VER < 1800)
63+
#error This version of MSVC has not been tested.
64+
#elif _MSC_VER >= 1900 // VC++ 2015 / 2017 / 2019
65+
#define CRTDLL_BASENAME "vcruntime140"
66+
#elif _MSC_VER >= 1800 // VC++ 2013
67+
#define CRTDLL_BASENAME "msvcr120"
68+
#endif
69+
#else
70+
#define CRTDLL_BASENAME "msvcrt"
71+
#endif
72+
73+
const char jl_crtdll_basename[] = CRTDLL_BASENAME;
74+
const char jl_crtdll_name[] = CRTDLL_BASENAME ".dll";
75+
76+
#undef CRTDLL_BASENAME
77+
#endif
78+
6079
#define PATHBUF 4096
6180

6281
#define JL_RTLD(flags, FLAG) (flags & JL_RTLD_ ## FLAG ? RTLD_ ## FLAG : 0)
@@ -314,18 +333,10 @@ const char *jl_dlfind_win32(const char *f_name)
314333
return JL_LIBJULIA_DL_LIBNAME;
315334
if (jl_dlsym(jl_kernel32_handle, f_name, &dummy, 0))
316335
return "kernel32";
336+
if (jl_dlsym(jl_crtdll_handle, f_name, &dummy, 0)) // Prefer crtdll over ntdll
337+
return jl_crtdll_basename;
317338
if (jl_dlsym(jl_ntdll_handle, f_name, &dummy, 0))
318339
return "ntdll";
319-
if (jl_dlsym(jl_crtdll_handle, f_name, &dummy, 0))
320-
#if defined(_MSC_VER)
321-
#if _MSC_VER == 1800
322-
return "msvcr120";
323-
#else
324-
#error This version of MSVC has not been tested.
325-
#endif
326-
#else
327-
return "msvcrt";
328-
#endif
329340
if (jl_dlsym(jl_winsock_handle, f_name, &dummy, 0))
330341
return "ws2_32";
331342
// additional common libraries (libc?) could be added here, but in general,

src/init.c

+2-5
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ void *jl_ntdll_handle;
302302
void *jl_kernel32_handle;
303303
void *jl_crtdll_handle;
304304
void *jl_winsock_handle;
305+
extern const char jl_crtdll_name[];
305306
#endif
306307

307308
uv_loop_t *jl_io_loop;
@@ -665,11 +666,7 @@ void _julia_init(JL_IMAGE_SEARCH rel)
665666
#ifdef _OS_WINDOWS_
666667
jl_ntdll_handle = jl_dlopen("ntdll.dll", 0); // bypass julia's pathchecking for system dlls
667668
jl_kernel32_handle = jl_dlopen("kernel32.dll", 0);
668-
#if defined(_MSC_VER) && _MSC_VER == 1800
669-
jl_crtdll_handle = jl_dlopen("msvcr120.dll", 0);
670-
#else
671-
jl_crtdll_handle = jl_dlopen("msvcrt.dll", 0);
672-
#endif
669+
jl_crtdll_handle = jl_dlopen(jl_crtdll_name, 0);
673670
jl_winsock_handle = jl_dlopen("ws2_32.dll", 0);
674671
jl_exe_handle = GetModuleHandleA(NULL);
675672
JL_MUTEX_INIT(&jl_in_stackwalk);

test/ccall.jl

+13
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,19 @@ let
15761576
@test arr[1] == '0'
15771577
end
15781578

1579+
# issue #38751
1580+
let
1581+
function f38751!(dest::Vector{UInt8}, src::Vector{UInt8}, n::UInt)
1582+
d, s = pointer(dest), pointer(src)
1583+
GC.@preserve dest src ccall(:memcpy, Cvoid, (Ptr{UInt8}, Ptr{UInt8}, Csize_t), d, s, n)
1584+
return dest
1585+
end
1586+
dest = zeros(UInt8, 8)
1587+
@test f38751!(dest, collect(0x1:0x8), UInt(8)) == 0x1:0x8
1588+
llvm = sprint(code_llvm, f38751!, (Vector{UInt8}, Vector{UInt8}, UInt))
1589+
@test !occursin("call void inttoptr", llvm)
1590+
end
1591+
15791592
# issue #34061
15801593
let o_file = tempname(), err = Base.PipeEndpoint()
15811594
run(pipeline(Cmd(`$(Base.julia_cmd()) --output-o=$o_file -e 'Base.reinit_stdio();

0 commit comments

Comments
 (0)