Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/COFFVCRuntimeSupport.cpp
35294 views
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
9
#include "llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h"
10
11
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
12
#include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h"
13
#include "llvm/Support/VirtualFileSystem.h"
14
#include "llvm/WindowsDriver/MSVCPaths.h"
15
16
#define DEBUG_TYPE "orc"
17
18
using namespace llvm;
19
using namespace llvm::orc;
20
using namespace llvm::orc::shared;
21
22
Expected<std::unique_ptr<COFFVCRuntimeBootstrapper>>
23
COFFVCRuntimeBootstrapper::Create(ExecutionSession &ES,
24
ObjectLinkingLayer &ObjLinkingLayer,
25
const char *RuntimePath) {
26
return std::unique_ptr<COFFVCRuntimeBootstrapper>(
27
new COFFVCRuntimeBootstrapper(ES, ObjLinkingLayer, RuntimePath));
28
}
29
30
COFFVCRuntimeBootstrapper::COFFVCRuntimeBootstrapper(
31
ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
32
const char *RuntimePath)
33
: ES(ES), ObjLinkingLayer(ObjLinkingLayer) {
34
if (RuntimePath)
35
this->RuntimePath = RuntimePath;
36
}
37
38
Expected<std::vector<std::string>>
39
COFFVCRuntimeBootstrapper::loadStaticVCRuntime(JITDylib &JD,
40
bool DebugVersion) {
41
StringRef VCLibs[] = {"libvcruntime.lib", "libcmt.lib", "libcpmt.lib"};
42
StringRef UCRTLibs[] = {"libucrt.lib"};
43
std::vector<std::string> ImportedLibraries;
44
if (auto Err = loadVCRuntime(JD, ImportedLibraries, ArrayRef(VCLibs),
45
ArrayRef(UCRTLibs)))
46
return std::move(Err);
47
return ImportedLibraries;
48
}
49
50
Expected<std::vector<std::string>>
51
COFFVCRuntimeBootstrapper::loadDynamicVCRuntime(JITDylib &JD,
52
bool DebugVersion) {
53
StringRef VCLibs[] = {"vcruntime.lib", "msvcrt.lib", "msvcprt.lib"};
54
StringRef UCRTLibs[] = {"ucrt.lib"};
55
std::vector<std::string> ImportedLibraries;
56
if (auto Err = loadVCRuntime(JD, ImportedLibraries, ArrayRef(VCLibs),
57
ArrayRef(UCRTLibs)))
58
return std::move(Err);
59
return ImportedLibraries;
60
}
61
62
Error COFFVCRuntimeBootstrapper::loadVCRuntime(
63
JITDylib &JD, std::vector<std::string> &ImportedLibraries,
64
ArrayRef<StringRef> VCLibs, ArrayRef<StringRef> UCRTLibs) {
65
MSVCToolchainPath Path;
66
if (!RuntimePath.empty()) {
67
Path.UCRTSdkLib = RuntimePath;
68
Path.VCToolchainLib = RuntimePath;
69
} else {
70
auto ToolchainPath = getMSVCToolchainPath();
71
if (!ToolchainPath)
72
return ToolchainPath.takeError();
73
Path = *ToolchainPath;
74
}
75
LLVM_DEBUG({
76
dbgs() << "Using VC toolchain pathes\n";
77
dbgs() << " VC toolchain path: " << Path.VCToolchainLib << "\n";
78
dbgs() << " UCRT path: " << Path.UCRTSdkLib << "\n";
79
});
80
81
auto LoadLibrary = [&](SmallString<256> LibPath, StringRef LibName) -> Error {
82
sys::path::append(LibPath, LibName);
83
84
auto G = StaticLibraryDefinitionGenerator::Load(ObjLinkingLayer,
85
LibPath.c_str());
86
if (!G)
87
return G.takeError();
88
89
for (auto &Lib : (*G)->getImportedDynamicLibraries())
90
ImportedLibraries.push_back(Lib);
91
92
JD.addGenerator(std::move(*G));
93
94
return Error::success();
95
};
96
for (auto &Lib : UCRTLibs)
97
if (auto Err = LoadLibrary(Path.UCRTSdkLib, Lib))
98
return Err;
99
100
for (auto &Lib : VCLibs)
101
if (auto Err = LoadLibrary(Path.VCToolchainLib, Lib))
102
return Err;
103
ImportedLibraries.push_back("ntdll.dll");
104
ImportedLibraries.push_back("Kernel32.dll");
105
106
return Error::success();
107
}
108
109
Error COFFVCRuntimeBootstrapper::initializeStaticVCRuntime(JITDylib &JD) {
110
ExecutorAddr jit_scrt_initialize, jit_scrt_dllmain_before_initialize_c,
111
jit_scrt_initialize_type_info,
112
jit_scrt_initialize_default_local_stdio_options;
113
if (auto Err = lookupAndRecordAddrs(
114
ES, LookupKind::Static, makeJITDylibSearchOrder(&JD),
115
{{ES.intern("__scrt_initialize_crt"), &jit_scrt_initialize},
116
{ES.intern("__scrt_dllmain_before_initialize_c"),
117
&jit_scrt_dllmain_before_initialize_c},
118
{ES.intern("?__scrt_initialize_type_info@@YAXXZ"),
119
&jit_scrt_initialize_type_info},
120
{ES.intern("__scrt_initialize_default_local_stdio_options"),
121
&jit_scrt_initialize_default_local_stdio_options}}))
122
return Err;
123
124
auto RunVoidInitFunc = [&](ExecutorAddr Addr) -> Error {
125
if (auto Res = ES.getExecutorProcessControl().runAsVoidFunction(Addr))
126
return Error::success();
127
else
128
return Res.takeError();
129
};
130
131
auto R =
132
ES.getExecutorProcessControl().runAsIntFunction(jit_scrt_initialize, 0);
133
if (!R)
134
return R.takeError();
135
136
if (auto Err = RunVoidInitFunc(jit_scrt_dllmain_before_initialize_c))
137
return Err;
138
139
if (auto Err = RunVoidInitFunc(jit_scrt_initialize_type_info))
140
return Err;
141
142
if (auto Err =
143
RunVoidInitFunc(jit_scrt_initialize_default_local_stdio_options))
144
return Err;
145
146
SymbolAliasMap Alias;
147
Alias[ES.intern("__run_after_c_init")] = {
148
ES.intern("__scrt_dllmain_after_initialize_c"), JITSymbolFlags::Exported};
149
if (auto Err = JD.define(symbolAliases(Alias)))
150
return Err;
151
152
return Error::success();
153
}
154
155
Expected<COFFVCRuntimeBootstrapper::MSVCToolchainPath>
156
COFFVCRuntimeBootstrapper::getMSVCToolchainPath() {
157
std::string VCToolChainPath;
158
ToolsetLayout VSLayout;
159
IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem();
160
if (!findVCToolChainViaCommandLine(*VFS, std::nullopt, std::nullopt,
161
std::nullopt, VCToolChainPath, VSLayout) &&
162
!findVCToolChainViaEnvironment(*VFS, VCToolChainPath, VSLayout) &&
163
!findVCToolChainViaSetupConfig(*VFS, {}, VCToolChainPath, VSLayout) &&
164
!findVCToolChainViaRegistry(VCToolChainPath, VSLayout))
165
return make_error<StringError>("Couldn't find msvc toolchain.",
166
inconvertibleErrorCode());
167
168
std::string UniversalCRTSdkPath;
169
std::string UCRTVersion;
170
if (!getUniversalCRTSdkDir(*VFS, std::nullopt, std::nullopt, std::nullopt,
171
UniversalCRTSdkPath, UCRTVersion))
172
return make_error<StringError>("Couldn't find universal sdk.",
173
inconvertibleErrorCode());
174
175
MSVCToolchainPath ToolchainPath;
176
SmallString<256> VCToolchainLib(VCToolChainPath);
177
sys::path::append(VCToolchainLib, "lib", "x64");
178
ToolchainPath.VCToolchainLib = VCToolchainLib;
179
180
SmallString<256> UCRTSdkLib(UniversalCRTSdkPath);
181
sys::path::append(UCRTSdkLib, "Lib", UCRTVersion, "ucrt", "x64");
182
ToolchainPath.UCRTSdkLib = UCRTSdkLib;
183
return ToolchainPath;
184
}
185
186