From 3535baac17d456bc3731e685af1a00fe4aa404d1 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sat, 17 Oct 2026 15:43:50 +0000 Subject: fix(driver): resolve JIT C symbols from msvcrt.dll first on Windows Process-wide lookup can bind EXTERN functions such as puts to ucrtbase.dll, whose stdout buffer is separate from the host msvcrt used by OUTPUT, so redirected output can come out of order. Co-Authored-By: Claude Opus 5.5 --- tools/driver/EmbeddedRunner.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'tools') diff --git a/tools/driver/EmbeddedRunner.cc b/tools/driver/EmbeddedRunner.cc index 3216882..742a6e4 100644 --- a/tools/driver/EmbeddedRunner.cc +++ b/tools/driver/EmbeddedRunner.cc @@ -1,6 +1,7 @@ #include "EmbeddedRunner.h" #include "cps/CodeGen.h" #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" @@ -387,6 +388,19 @@ int runEmbedded(const cps::CodeGen &CG, const std::vector &Objects) << llvm::toString(std::move(Err)) << "\n"; return 1; } +#ifdef _WIN32 + // Process-wide lookup may find C functions in ucrtbase.dll, loaded by + // system DLLs, whose stdio buffers differ from the host's msvcrt. Prefer + // the host CRT so EXTERN calls such as puts share stdout with OUTPUT. + auto CRT = llvm::orc::DynamicLibrarySearchGenerator::Load( + "msvcrt.dll", J->getDataLayout().getGlobalPrefix()); + if (!CRT) { + llvm::errs() << "error: cannot load the embedded C runtime: " + << llvm::toString(CRT.takeError()) << "\n"; + return 1; + } + J->getMainJITDylib().addGenerator(std::move(*CRT)); +#endif // Keep CodeGen's module and context alive; the JIT owns an independent copy. llvm::orc::ThreadSafeContext TSCtx(std::make_unique()); -- cgit v1.3.1-4-g156e