From cf0fb69b3d489cd0aebaa2d759b2d2c0c4e230b1 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Mon, 19 Oct 2026 10:51:13 +0000 Subject: fix(driver): normalize MinGW JIT archive symbol definitions Make absolute-zero pure virtual fallbacks local and compute runtime archive interfaces from normalized objects so ORC definitions match JITLink. Co-Authored-By: Claude Opus 5.5 --- tools/driver/EmbeddedRunner.cc | 15 ++++++++++++++- tools/driver/MinGWCOFF.h | 12 ++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'tools/driver') diff --git a/tools/driver/EmbeddedRunner.cc b/tools/driver/EmbeddedRunner.cc index 28fe2db..c8c3fcd 100644 --- a/tools/driver/EmbeddedRunner.cc +++ b/tools/driver/EmbeddedRunner.cc @@ -5,6 +5,7 @@ #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" +#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h" #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" #include "llvm/Support/Error.h" @@ -439,6 +440,18 @@ static llvm::Error loadCxxRuntime(llvm::orc::LLJIT &J) { if (!unpackCxxRuntime(Archives)) return llvm::make_error("cannot unpack the C++ runtime", llvm::inconvertibleErrorCode()); for (auto &Archive : Archives) { + llvm::orc::StaticLibraryDefinitionGenerator::GetObjectFileInterface GetInterface; +#if defined(_WIN32) && defined(__x86_64__) + // Match the normalized object that MinGWObjectLinkingLayer::emit links. + GetInterface = [](llvm::orc::ExecutionSession &ES, llvm::MemoryBufferRef Ref) + -> llvm::Expected { + auto Normalized = normalizeMinGWObject( + llvm::MemoryBuffer::getMemBuffer(Ref, false)); + if (!Normalized) + return Normalized.takeError(); + return llvm::orc::getObjectFileInterface(ES, (*Normalized)->getMemBufferRef()); + }; +#endif auto Generator = llvm::orc::StaticLibraryDefinitionGenerator::Create( J.getObjLinkingLayer(), std::move(Archive), [](llvm::object::Archive &, llvm::MemoryBufferRef Buffer, size_t) -> llvm::Expected { @@ -458,7 +471,7 @@ static llvm::Error loadCxxRuntime(llvm::orc::LLJIT &J) { N.starts_with("_Unwind_") || N == "_ZTIi") return false; } return true; - }); + }, std::move(GetInterface)); if (!Generator) return Generator.takeError(); J.getMainJITDylib().addGenerator(std::move(*Generator)); } diff --git a/tools/driver/MinGWCOFF.h b/tools/driver/MinGWCOFF.h index 186d981..555dcc8 100644 --- a/tools/driver/MinGWCOFF.h +++ b/tools/driver/MinGWCOFF.h @@ -50,6 +50,7 @@ normalizeMinGWObject(std::unique_ptr Buffer) { struct Association { size_t Offset; int32_t Parent; }; SmallVector Associations; SmallVector PureVirtualReferences; + SmallVector PureVirtualFallbacks; for (const auto &Symbol : COFF->symbols()) { auto Sym = COFF->getCOFFSymbol(Symbol); if (auto *Weak = Sym.getWeakExternal()) { @@ -68,6 +69,13 @@ normalizeMinGWObject(std::unique_ptr Buffer) { ? offsetof(object::coff_symbol32, StorageClass) : offsetof(object::coff_symbol16, StorageClass); PureVirtualReferences.push_back(Offset); + size_t FallbackOffset = + reinterpret_cast(Fallback->getRawPtr()) - + Buffer->getBufferStart(); + FallbackOffset += Fallback->isBigObj() + ? offsetof(object::coff_symbol32, StorageClass) + : offsetof(object::coff_symbol16, StorageClass); + PureVirtualFallbacks.push_back(FallbackOffset); } } } @@ -118,6 +126,10 @@ normalizeMinGWObject(std::unique_ptr Buffer) { // entry count intact so the remaining symbol indices do not move. for (size_t Offset : PureVirtualReferences) Copy->getBufferStart()[Offset] = COFF::IMAGE_SYM_CLASS_EXTERNAL; + // Only the now-unused weak auxiliary record references the fallback. + // Keep it local so archive interfaces do not advertise a global definition. + for (size_t Offset : PureVirtualFallbacks) + Copy->getBufferStart()[Offset] = COFF::IMAGE_SYM_CLASS_STATIC; return std::unique_ptr(std::move(Copy)); } -- cgit v1.3.1-4-g156e