whitequark opened Issue #1738:
I was looking into developing the Windows backend of Cranelift/wasmtime on Linux using cross-compilation and wine, and it actually works quite well, with one exception: I have to comment out the setjmp helper, because if I don't, this happens:
$ cargo run --target x86_64-pc-windows-gnu hello.wasm Finished dev [unoptimized + debuginfo] target(s) in 0.12s Running `target/x86_64-pc-windows-gnu/debug/wasmtime.exe hello.wasm` wine: Call from 0x7bc5d60c to unimplemented function ntdll.dll._setjmp, aborting wine: Unimplemented function ntdll.dll._setjmp called at address 0x7bc5d60c (thread 003e), starting debugger...
This clearly looks like a bug in wine of some sort, but given that setjmp is a pervasive function and it's neither implemented in wine nor can I find any similar bug reports, what wasmtime does here is at least unusual. What gives?
whitequark labeled Issue #1738:
I was looking into developing the Windows backend of Cranelift/wasmtime on Linux using cross-compilation and wine, and it actually works quite well, with one exception: I have to comment out the setjmp helper, because if I don't, this happens:
$ cargo run --target x86_64-pc-windows-gnu hello.wasm Finished dev [unoptimized + debuginfo] target(s) in 0.12s Running `target/x86_64-pc-windows-gnu/debug/wasmtime.exe hello.wasm` wine: Call from 0x7bc5d60c to unimplemented function ntdll.dll._setjmp, aborting wine: Unimplemented function ntdll.dll._setjmp called at address 0x7bc5d60c (thread 003e), starting debugger...
This clearly looks like a bug in wine of some sort, but given that setjmp is a pervasive function and it's neither implemented in wine nor can I find any similar bug reports, what wasmtime does here is at least unusual. What gives?
whitequark commented on Issue #1738:
Er, I think I chose the wrong issue template--I'm not really sure if this is a bug in wasmtime.
whitequark commented on Issue #1738:
According to this page ntdll.dll indeed exports
_setjmp
and it is undocumented, so maybe wasmtime shouldn't really be using it?
bjorn3 commented on Issue #1738:
The only reference to
setjmp
I could find is https://github.com/bytecodealliance/wasmtime/blob/962f057c8a0e42bcba33850d412d77e5de5830fb/crates/runtime/src/helpers.c#L8 which imports it fromsetjmp.h
. This is a header defined by the C specification.
whitequark commented on Issue #1738:
I believe the problem is that wasmtime uses a C runtime function but does not link to C runtime. Things happen to work pretty much by accident because ntdll happens to expose that function too. If I comment out the
#[link = "ntdll"]
and add#[link = "ucrt"] extern "C" {}
then things work as I expect.
whitequark commented on Issue #1738:
It is actually not necessary to link to
ucrt
explicitly. What is necessary is to not link tontdll
, since for some reason the_setjmp
symbol from ntdll is preferred compared to the symbol frommsvcrt
.
alexcrichton commented on Issue #1738:
The
setjmp
/longjmp
functions are used to implement traps right now in wasmtime. They're used to jump over all the JIT code back to the original caller. IIRC there's actually a few setjmp-like functions on Windows, and we had to historically be quite careful about which precise one that we used.I suspect that what's happening here is that the header we're using ends up mapping our call to
_setjmp
and thesetjmp
symbol (no leading underscore) is actually different and defined elsewhere. I'm not sure if one is particularly more canonical than the other, but if the baresetjmp
symbol is the way to go then it seems reasonable to add!I'm not personally too too familiar with how this works on Windows and how you'd select between them (or how they're different, really)
whitequark commented on Issue #1738:
@alexcrichton It appears to me that the problem is that the linker command line includes the following:
"-ladvapi32" "-lntdll" "-lwinapi_advapi32" "-lwinapi_cfgmgr32" "-lwinapi_gdi32" "-lwinapi_kernel32" "-lwinapi_msimg32" "-lwinapi_ole32" "-lwinapi_opengl32" "-lwinapi_shell32" "-lwinapi_user32" "-lwinapi_winspool" "-ladvapi32" "-lws2_32" "-luserenv" "-lmingwex" "-lmingw32" "-lmsvcrt" "-lmsvcrt" "-luser32" "-lkernel32" "-lgcc_eh" "-l:libpthread.a" "-lgcc" "-lmsvcrt" "-lkernel32"
where as you can seentdll
appears earlier thanmsvcrt
and so it is searched earlier. Is there a way to control the order here?
whitequark commented on Issue #1738:
@alexcrichton Scratch that, I removed the
#[link = "ntdll"]
and added it back viaRUSTFLAGS="-C link-arg=-Wl,--allow-multiple-definition -C link-arg=-lmsvcrt -C link-arg=-lntdll -Z print-link-args"
but this just segfaults ld. Can we grabNtQueryInformationFile
viaGetProcAddress
instead?
whitequark commented on Issue #1738:
See #1739.
alexcrichton closed Issue #1738:
I was looking into developing the Windows backend of Cranelift/wasmtime on Linux using cross-compilation and wine, and it actually works quite well, with one exception: I have to comment out the setjmp helper, because if I don't, this happens:
$ cargo run --target x86_64-pc-windows-gnu hello.wasm Finished dev [unoptimized + debuginfo] target(s) in 0.12s Running `target/x86_64-pc-windows-gnu/debug/wasmtime.exe hello.wasm` wine: Call from 0x7bc5d60c to unimplemented function ntdll.dll._setjmp, aborting wine: Unimplemented function ntdll.dll._setjmp called at address 0x7bc5d60c (thread 003e), starting debugger...
This clearly looks like a bug in wine of some sort, but given that setjmp is a pervasive function and it's neither implemented in wine nor can I find any similar bug reports, what wasmtime does here is at least unusual. What gives?
Last updated: Dec 23 2024 at 12:05 UTC