LLVM 24.0.0git
COFFVCRuntimeSupport.cpp
Go to the documentation of this file.
1//===------- COFFVCRuntimeSupport.cpp - VC runtime support in ORC ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
18
19#define DEBUG_TYPE "orc"
20
21using namespace llvm;
22using namespace llvm::orc;
23using namespace llvm::orc::shared;
24
27 ObjectLinkingLayer &ObjLinkingLayer,
28 const char *RuntimePath) {
29 return std::unique_ptr<COFFVCRuntimeBootstrapper>(
30 new COFFVCRuntimeBootstrapper(ES, ObjLinkingLayer, RuntimePath));
31}
32
33COFFVCRuntimeBootstrapper::COFFVCRuntimeBootstrapper(
34 ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
35 const char *RuntimePath)
36 : ES(ES), ObjLinkingLayer(ObjLinkingLayer) {
37 if (RuntimePath)
38 this->RuntimePath = RuntimePath;
39}
40
43 bool DebugVersion) {
44 StringRef VCLibs[] = {"libvcruntime.lib", "libcmt.lib", "libcpmt.lib"};
45 StringRef UCRTLibs[] = {"libucrt.lib"};
46 std::vector<std::string> ImportedLibraries;
47 if (auto Err = loadVCRuntime(JD, ImportedLibraries, ArrayRef(VCLibs),
48 ArrayRef(UCRTLibs)))
49 return std::move(Err);
50 return ImportedLibraries;
51}
52
55 bool DebugVersion) {
56 StringRef VCLibs[] = {"vcruntime.lib", "msvcrt.lib", "msvcprt.lib"};
57 StringRef UCRTLibs[] = {"ucrt.lib"};
58 std::vector<std::string> ImportedLibraries;
59 if (auto Err = loadVCRuntime(JD, ImportedLibraries, ArrayRef(VCLibs),
60 ArrayRef(UCRTLibs)))
61 return std::move(Err);
62 return ImportedLibraries;
63}
64
65Error COFFVCRuntimeBootstrapper::loadVCRuntime(
66 JITDylib &JD, std::vector<std::string> &ImportedLibraries,
68 MSVCToolchainPath Path;
69 if (!RuntimePath.empty()) {
70 Path.UCRTSdkLib = RuntimePath;
71 Path.VCToolchainLib = RuntimePath;
72 } else {
73 auto ToolchainPath = getMSVCToolchainPath();
74 if (!ToolchainPath)
75 return ToolchainPath.takeError();
76 Path = *ToolchainPath;
77 }
79 dbgs() << "Using VC toolchain pathes\n";
80 dbgs() << " VC toolchain path: " << Path.VCToolchainLib << "\n";
81 dbgs() << " UCRT path: " << Path.UCRTSdkLib << "\n";
82 });
83
84 auto LoadLibrary = [&](SmallString<256> LibPath, StringRef LibName) -> Error {
85 sys::path::append(LibPath, LibName);
86
87 std::set<std::string> NewImportedLibraries;
89 ObjLinkingLayer, LibPath.c_str(),
90 COFFImportFileScanner(NewImportedLibraries));
91 if (!G)
92 return G.takeError();
93
94 llvm::append_range(ImportedLibraries, NewImportedLibraries);
95
96 JD.addGenerator(std::move(*G));
97
98 return Error::success();
99 };
100 for (auto &Lib : UCRTLibs)
101 if (auto Err = LoadLibrary(Path.UCRTSdkLib, Lib))
102 return Err;
103
104 for (auto &Lib : VCLibs)
105 if (auto Err = LoadLibrary(Path.VCToolchainLib, Lib))
106 return Err;
107 ImportedLibraries.push_back("ntdll.dll");
108 ImportedLibraries.push_back("Kernel32.dll");
109
110 return Error::success();
111}
112
114 ExecutorAddr jit_scrt_initialize, jit_scrt_dllmain_before_initialize_c,
115 jit_scrt_initialize_type_info,
116 jit_scrt_initialize_default_local_stdio_options;
117 if (auto Err = lookupAndApply(
118 JD, {recordAddr("__scrt_initialize_crt", &jit_scrt_initialize),
119 recordAddr("__scrt_dllmain_before_initialize_c",
120 &jit_scrt_dllmain_before_initialize_c),
121 recordAddr("?__scrt_initialize_type_info@@YAXXZ",
122 &jit_scrt_initialize_type_info),
123 recordAddr("__scrt_initialize_default_local_stdio_options",
124 &jit_scrt_initialize_default_local_stdio_options)}))
125 return Err;
126
127 CallInt32VoidProxy CallInt32Void;
128 CallInt32Int32Proxy CallInt32Int32;
129 if (auto Err = lookupAndApply(
130 ES.getBootstrapJITDylib(),
131 {recordProxy<sps::CallInt32VoidProxySpec>(&CallInt32Void),
132 recordProxy<sps::CallInt32Int32ProxySpec>(&CallInt32Int32)}))
133 return Err;
134
135 auto R = CallInt32Int32(ES, jit_scrt_initialize, 0);
136 if (!R)
137 return R.takeError();
138
139 if (auto Err =
140 CallInt32Void(ES, jit_scrt_dllmain_before_initialize_c).takeError())
141 return Err;
142
143 if (auto Err = CallInt32Void(ES, jit_scrt_initialize_type_info).takeError())
144 return Err;
145
146 if (auto Err =
147 CallInt32Void(ES, jit_scrt_initialize_default_local_stdio_options)
148 .takeError())
149 return Err;
150
151 SymbolAliasMap Alias;
152 Alias[ES.intern("__run_after_c_init")] = {
153 ES.intern("__scrt_dllmain_after_initialize_c"), JITSymbolFlags::Exported};
154 if (auto Err = JD.define(symbolAliases(Alias)))
155 return Err;
156
157 return Error::success();
158}
159
161COFFVCRuntimeBootstrapper::getMSVCToolchainPath() {
162 std::string VCToolChainPath;
163 ToolsetLayout VSLayout;
165 if (!findVCToolChainViaCommandLine(*VFS, std::nullopt, std::nullopt,
166 std::nullopt, VCToolChainPath, VSLayout) &&
167 !findVCToolChainViaEnvironment(*VFS, VCToolChainPath, VSLayout) &&
168 !findVCToolChainViaSetupConfig(*VFS, {}, VCToolChainPath, VSLayout) &&
169 !findVCToolChainViaRegistry(VCToolChainPath, VSLayout))
170 return make_error<StringError>("Couldn't find msvc toolchain.",
172
173 std::string UniversalCRTSdkPath;
174 std::string UCRTVersion;
175 if (!getUniversalCRTSdkDir(*VFS, std::nullopt, std::nullopt, std::nullopt,
176 UniversalCRTSdkPath, UCRTVersion))
177 return make_error<StringError>("Couldn't find universal sdk.",
179
180 MSVCToolchainPath ToolchainPath;
181 SmallString<256> VCToolchainLib(VCToolChainPath);
182 sys::path::append(VCToolchainLib, "lib", "x64");
183 ToolchainPath.VCToolchainLib = std::move(VCToolchainLib);
184
185 SmallString<256> UCRTSdkLib(UniversalCRTSdkPath);
186 sys::path::append(UCRTSdkLib, "Lib", UCRTVersion, "ucrt", "x64");
187 ToolchainPath.UCRTSdkLib = std::move(UCRTSdkLib);
188 return ToolchainPath;
189}
#define G(x, y, z)
Definition MD5.cpp:55
#define LLVM_DEBUG(...)
Definition Debug.h:119
Defines the virtual file system interface vfs::FileSystem.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
const char * c_str()
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
static LLVM_ABI Expected< std::unique_ptr< COFFVCRuntimeBootstrapper > > Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, const char *RuntimePath=nullptr)
Try to create a COFFVCRuntimeBootstrapper instance.
LLVM_ABI Expected< std::vector< std::string > > loadStaticVCRuntime(JITDylib &JD, bool DebugVersion=false)
Adds symbol definitions of static version of msvc runtime libraries.
LLVM_ABI Expected< std::vector< std::string > > loadDynamicVCRuntime(JITDylib &JD, bool DebugVersion=false)
Adds symbol definitions of dynamic version of msvc runtime libraries.
LLVM_ABI Error initializeStaticVCRuntime(JITDylib &JD)
Runs the initializer of static version of msvc runtime libraries.
An ExecutionSession represents a running JIT program.
Definition Core.h:1111
Represents an address in the executor process.
Represents a JIT'd dynamic library.
Definition Core.h:675
Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)
Define all symbols provided by the materialization unit to be part of this JITDylib.
Definition Core.h:1654
GeneratorT & addGenerator(std::unique_ptr< GeneratorT > DefGenerator)
Adds a definition generator to this JITDylib and returns a referenece to it.
Definition Core.h:1637
An ObjectLayer implementation built on JITLink.
static Expected< std::unique_ptr< StaticLibraryDefinitionGenerator > > Load(ObjectLayer &L, const char *FileName, VisitMembersFunction VisitMembers=VisitMembersFunction(), GetObjectFileInterface GetObjFileInterface=GetObjectFileInterface())
Try to create a StaticLibraryDefinitionGenerator from the given path.
Proxy< int32_t(ExecutorAddr)> CallInt32VoidProxy
Protocol-agnostic interface for running an int32_t() function in the executor.
Definition CallProxies.h:45
std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)
Create a ReExportsMaterializationUnit with the given aliases.
Definition Core.h:523
Proxy< int32_t(ExecutorAddr, int32_t)> CallInt32Int32Proxy
Protocol-agnostic interface for running an int32_t(int32_t) function in the executor.
Definition CallProxies.h:53
LLVM_ABI void lookupAndApply(unique_function< void(Error)> OnApplied, ExecutionSession &ES, LookupKind K, const JITDylibSearchOrder &SearchOrder, ArrayRef< LookupPrepareFn > PrepareFns)
Resolve the symbols contributed by every prepare function with a single lookup, then let each of thei...
LookupPrepareFn recordAddr(StringRef Name, ExecutorAddr *A, SymbolLookupFlags LF=SymbolLookupFlags::RequiredSymbol)
Records the address of the symbol with the given name.
DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap
A map of Symbols to (Symbol, Flags) pairs.
Definition Core.h:173
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:467
LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool findVCToolChainViaCommandLine(vfs::FileSystem &VFS, std::optional< llvm::StringRef > VCToolsDir, std::optional< llvm::StringRef > VCToolsVersion, std::optional< llvm::StringRef > WinSysRoot, std::string &Path, ToolsetLayout &VSLayout)
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
LLVM_ABI bool findVCToolChainViaEnvironment(vfs::FileSystem &VFS, std::string &Path, ToolsetLayout &VSLayout)
LLVM_ABI bool findVCToolChainViaSetupConfig(vfs::FileSystem &VFS, std::optional< llvm::StringRef > VCToolsVersion, std::string &Path, ToolsetLayout &VSLayout)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
ToolsetLayout
Definition MSVCPaths.h:31
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool findVCToolChainViaRegistry(std::string &Path, ToolsetLayout &VSLayout)
LLVM_ABI bool getUniversalCRTSdkDir(vfs::FileSystem &VFS, std::optional< llvm::StringRef > WinSdkDir, std::optional< llvm::StringRef > WinSdkVersion, std::optional< llvm::StringRef > WinSysRoot, std::string &Path, std::string &UCRTVersion)