aboutsummaryrefslogtreecommitdiff
path: root/tools/driver/EmbeddedRunner.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 15:43:50 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 15:43:50 +0000
commit3535baac17d456bc3731e685af1a00fe4aa404d1 (patch)
treed9a728c5f8302d7b33a54b6010452635cd83dbc8 /tools/driver/EmbeddedRunner.cc
parent4bcf730d97de848b5d87671bf04beaf78905649b (diff)
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 <noreply@anthropic.com>
Diffstat (limited to 'tools/driver/EmbeddedRunner.cc')
-rw-r--r--tools/driver/EmbeddedRunner.cc14
1 files changed, 14 insertions, 0 deletions
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<std::string> &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<llvm::LLVMContext>());