diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-16 16:25:12 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-16 16:25:12 +0000 |
| commit | 838d636d42db87b91f8b37bd39ab71ed3dc90599 (patch) | |
| tree | a3298100e270bb3a1308915d579865eb0cb30b33 /tools | |
| parent | b5b1e5a2a684a1ec96fae3408d322b92c38354e6 (diff) | |
fix(jit): provide JIT-only stack probe without weak host reference
The weak ___chkstk_ms reference marked the host import weak on COFF and
segfaulted the compiler itself. Provide a JIT-only probe under a unique
name with the same page-touching behavior instead.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/driver/EmbeddedRunner.cc | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/tools/driver/EmbeddedRunner.cc b/tools/driver/EmbeddedRunner.cc index 8ebffab..0c1346f 100644 --- a/tools/driver/EmbeddedRunner.cc +++ b/tools/driver/EmbeddedRunner.cc @@ -276,10 +276,36 @@ __gxx_personality_v0 extern "C" void __cps_jit_noop__main() {} #endif -// MinGW inserts ___chkstk_ms stack probes into large frames. dlsym cannot see -// this static runtime symbol, so reference it weakly: null on platforms -// without it, host address where present. Same code on all platforms. -extern "C" void ___chkstk_ms() __attribute__((weak)); +// MinGW emits ___chkstk_ms stack probes for large frames with a custom +// convention (size in %eax, result in %rax, all else preserved). Never +// reference the host probe by name: a weak reference marks the host import +// weak on COFF and segfaults the compiler itself. Provide a JIT-only probe +// under a unique name and map the JIT symbol to it. Same code on all +// platforms; the stub is unused where the backend never emits the probe. +#if defined(__x86_64__) +extern "C" __attribute__((naked)) void __cps_jit_chkstk_ms() { + __asm__ volatile( + "pushq %rcx\n\t" + "pushq %rax\n\t" + "cmpq $0x1000, %rax\n\t" + "leaq 0x18(%rsp), %rcx\n\t" + "jb 1f\n\t" + "0:\n\t" + "subq $0x1000, %rcx\n\t" + "orq $0, (%rcx)\n\t" + "subq $0x1000, %rax\n\t" + "cmpq $0x1000, %rax\n\t" + "ja 0b\n\t" + "1:\n\t" + "subq %rax, %rcx\n\t" + "orq $0, (%rcx)\n\t" + "popq %rax\n\t" + "popq %rcx\n\t" + "ret\n\t"); +} +#else +extern "C" void __cps_jit_chkstk_ms() {} +#endif static llvm::Error defineRuntimeSymbols(llvm::orc::LLJIT &J) { llvm::orc::SymbolMap Symbols; @@ -322,9 +348,8 @@ static llvm::Error defineRuntimeSymbols(llvm::orc::LLJIT &J) { Symbols[Intern("__main")] = ExecutorSymbolDef::fromPtr(&__cps_jit_noop__main); #endif - if (___chkstk_ms) - Symbols[Intern("___chkstk_ms")] = - ExecutorSymbolDef::fromPtr(reinterpret_cast<void *>(&___chkstk_ms)); + Symbols[Intern("___chkstk_ms")] = + ExecutorSymbolDef::fromPtr(&__cps_jit_chkstk_ms); return J.getMainJITDylib().define( llvm::orc::absoluteSymbols(std::move(Symbols))); } |
