I built compiler-rt
16.0.0 for Windows x86-64 (on Windows x86-64, outside Cygwin), installed it by invoking cmake install-compiler-rt
target (outside Cygwin) with the default prefix C:\Program Files (x86)\Runtimes
, in that directory ran objdump -t lib/windows/clang_rt.builtins-x86_64.lib | grep -F __chkstk
(in Cygwin) and got empty output. Other artifacts there too seem to not have __chkstk
. So I don’t know which file with __chkstk
to link my program with (I don’t want to use MSVC runtime). How do i use __chkstk
with clang++ targeting Windows x86-64 without MSVC runtime?
See this article. __chkstk is a special stack protector: Dealing with __chkstk/__chkstk_ms when Cross-Compiling For Windows | Metric Panda Games
There are some workarounds described as well.
compiler-rt
defines __chkstk
and __chkstk_ms
; I want to use this routine (__chkstk
). What I don’t understand is why compiler-rt
’s build doesn’t have them, and consequently how to use the routine. Your linked article doesn’t answer this.
I inspected lib/builtins/CMakeLists.txt
and found the answer. The routines are built only if NOT MSVC
in cmake.
I don’t know whether compiler-rt depends on MSVC runtime if MSVC
. I would like to use compiler-rt in my program targeting the MSVC target without MSVC runtime (freestanding). Meanwhile, I’ll compile lib/builtins/x86_64/chkstk2.S
by itself.
Does compiler-rt
built using clang-cl
and targeting MSVC target depend on the MSVC runtime, even if the program does not use that?
After a whole half-day of investigation, I conclude that compiler-rt’s ___chkstk
is unsuitable for the code that clang emits for the MSVC target: compiler-rt’s ___chkstk
reserves stack space in addition to committing it, but clang expects __chkstk
to only commit it. Though, compiler-rt has ___chkstk_ms
which does exactly what clang wants __chkstk
to do.
One may want to request the correct version of __chkstk
in compiler-rt for MSVC target, maybe with another name that clang will use with special configuration to avoid clashing. Meanwhile, the body of ___chkstk_ms
works as __chkstk
without error.
It looks to me like only the MinGW versions of these functions have ever been used, and seem to be the correct ones. The other ones are entirely unused, and as you note, incorrect.
compiler-rt: add support for mingw-w64 in builtins · llvm/llvm-project@fbfed86 · GitHub and Add missing chkstk.S files from r242539 · llvm/llvm-project@c27de5b · GitHub added ___chkstk_ms
for both i386 and x86_64. However nothing ever generates calls to a function ___chkstk_ms
on i386. Then later Support for 32-bit mingw-w64 in compiler-rt. · llvm/llvm-project@40eb83b · GitHub added the functions __alloca
and ___chkstk
(with three underscores) for i386 and for x86_64. Nothing ever calls ___chkstk
with three underscores, and AFAIK nothing calls __alloca
on x86_64 either.
So to clear this up, I would suggest we should do this:
- Remove
compiler-rt/lib/builtins/i386/chkstk.S
entirely - In
compiler-rt/lib/builtins/i386/chkstk2.S
, remove one superfluous leading underscore from___chkstk
(asDEFINE_COMPILERRT_FUNCTION
adds one extra leading underscore on i386 here) - Maybe rename
i386/chkstk2.S
toi386/chkstk.S
- Remove
compiler-rt/lib/builtins/x86_64/chkstk2.S
- Add
DEFINE_COMPILERRT_FUNCTION(__chkstk)
inx86_64/chkstk.S
Then these implementations should work just as well for both MSVC and MinGW targets. As far as I know, both targets want to have functions that do exactly the same, they just call it with slightly different names.
Would that solve your issue?
The second question is whether these symbols should be included by default in an MSVC mode build of the builtins - I’m less sure about that. Normally in an MSVC build, the MSVC libraries provide these functions, and compiler-rt’s builtins can be used to add extra functions on top of it. In such a case, we wouldn’t want to use compiler-rt’s implementation instead of the MSVC one. (IIRC the MSVC implementation of the functions doesn’t blindly probe the stack but checks StackLimit
from the TEB and only probes it if needed.)
I would be happy with a version of __chkstk
that clang can use (when generating) on MSVC target when the MSVC runtime is not used (-nostdlib
to clang), it may have a different name, like __chkstk_no_msvc
or something. Currently, (on MSVC target) clang expects that __chkstk
doesn’t change the stack pointer.