Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/COFFVCRuntimeSupport.cpp
35294 views
//===------- COFFVCRuntimeSupport.cpp - VC runtime support in ORC ---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h"910#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"11#include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h"12#include "llvm/Support/VirtualFileSystem.h"13#include "llvm/WindowsDriver/MSVCPaths.h"1415#define DEBUG_TYPE "orc"1617using namespace llvm;18using namespace llvm::orc;19using namespace llvm::orc::shared;2021Expected<std::unique_ptr<COFFVCRuntimeBootstrapper>>22COFFVCRuntimeBootstrapper::Create(ExecutionSession &ES,23ObjectLinkingLayer &ObjLinkingLayer,24const char *RuntimePath) {25return std::unique_ptr<COFFVCRuntimeBootstrapper>(26new COFFVCRuntimeBootstrapper(ES, ObjLinkingLayer, RuntimePath));27}2829COFFVCRuntimeBootstrapper::COFFVCRuntimeBootstrapper(30ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,31const char *RuntimePath)32: ES(ES), ObjLinkingLayer(ObjLinkingLayer) {33if (RuntimePath)34this->RuntimePath = RuntimePath;35}3637Expected<std::vector<std::string>>38COFFVCRuntimeBootstrapper::loadStaticVCRuntime(JITDylib &JD,39bool DebugVersion) {40StringRef VCLibs[] = {"libvcruntime.lib", "libcmt.lib", "libcpmt.lib"};41StringRef UCRTLibs[] = {"libucrt.lib"};42std::vector<std::string> ImportedLibraries;43if (auto Err = loadVCRuntime(JD, ImportedLibraries, ArrayRef(VCLibs),44ArrayRef(UCRTLibs)))45return std::move(Err);46return ImportedLibraries;47}4849Expected<std::vector<std::string>>50COFFVCRuntimeBootstrapper::loadDynamicVCRuntime(JITDylib &JD,51bool DebugVersion) {52StringRef VCLibs[] = {"vcruntime.lib", "msvcrt.lib", "msvcprt.lib"};53StringRef UCRTLibs[] = {"ucrt.lib"};54std::vector<std::string> ImportedLibraries;55if (auto Err = loadVCRuntime(JD, ImportedLibraries, ArrayRef(VCLibs),56ArrayRef(UCRTLibs)))57return std::move(Err);58return ImportedLibraries;59}6061Error COFFVCRuntimeBootstrapper::loadVCRuntime(62JITDylib &JD, std::vector<std::string> &ImportedLibraries,63ArrayRef<StringRef> VCLibs, ArrayRef<StringRef> UCRTLibs) {64MSVCToolchainPath Path;65if (!RuntimePath.empty()) {66Path.UCRTSdkLib = RuntimePath;67Path.VCToolchainLib = RuntimePath;68} else {69auto ToolchainPath = getMSVCToolchainPath();70if (!ToolchainPath)71return ToolchainPath.takeError();72Path = *ToolchainPath;73}74LLVM_DEBUG({75dbgs() << "Using VC toolchain pathes\n";76dbgs() << " VC toolchain path: " << Path.VCToolchainLib << "\n";77dbgs() << " UCRT path: " << Path.UCRTSdkLib << "\n";78});7980auto LoadLibrary = [&](SmallString<256> LibPath, StringRef LibName) -> Error {81sys::path::append(LibPath, LibName);8283auto G = StaticLibraryDefinitionGenerator::Load(ObjLinkingLayer,84LibPath.c_str());85if (!G)86return G.takeError();8788for (auto &Lib : (*G)->getImportedDynamicLibraries())89ImportedLibraries.push_back(Lib);9091JD.addGenerator(std::move(*G));9293return Error::success();94};95for (auto &Lib : UCRTLibs)96if (auto Err = LoadLibrary(Path.UCRTSdkLib, Lib))97return Err;9899for (auto &Lib : VCLibs)100if (auto Err = LoadLibrary(Path.VCToolchainLib, Lib))101return Err;102ImportedLibraries.push_back("ntdll.dll");103ImportedLibraries.push_back("Kernel32.dll");104105return Error::success();106}107108Error COFFVCRuntimeBootstrapper::initializeStaticVCRuntime(JITDylib &JD) {109ExecutorAddr jit_scrt_initialize, jit_scrt_dllmain_before_initialize_c,110jit_scrt_initialize_type_info,111jit_scrt_initialize_default_local_stdio_options;112if (auto Err = lookupAndRecordAddrs(113ES, LookupKind::Static, makeJITDylibSearchOrder(&JD),114{{ES.intern("__scrt_initialize_crt"), &jit_scrt_initialize},115{ES.intern("__scrt_dllmain_before_initialize_c"),116&jit_scrt_dllmain_before_initialize_c},117{ES.intern("?__scrt_initialize_type_info@@YAXXZ"),118&jit_scrt_initialize_type_info},119{ES.intern("__scrt_initialize_default_local_stdio_options"),120&jit_scrt_initialize_default_local_stdio_options}}))121return Err;122123auto RunVoidInitFunc = [&](ExecutorAddr Addr) -> Error {124if (auto Res = ES.getExecutorProcessControl().runAsVoidFunction(Addr))125return Error::success();126else127return Res.takeError();128};129130auto R =131ES.getExecutorProcessControl().runAsIntFunction(jit_scrt_initialize, 0);132if (!R)133return R.takeError();134135if (auto Err = RunVoidInitFunc(jit_scrt_dllmain_before_initialize_c))136return Err;137138if (auto Err = RunVoidInitFunc(jit_scrt_initialize_type_info))139return Err;140141if (auto Err =142RunVoidInitFunc(jit_scrt_initialize_default_local_stdio_options))143return Err;144145SymbolAliasMap Alias;146Alias[ES.intern("__run_after_c_init")] = {147ES.intern("__scrt_dllmain_after_initialize_c"), JITSymbolFlags::Exported};148if (auto Err = JD.define(symbolAliases(Alias)))149return Err;150151return Error::success();152}153154Expected<COFFVCRuntimeBootstrapper::MSVCToolchainPath>155COFFVCRuntimeBootstrapper::getMSVCToolchainPath() {156std::string VCToolChainPath;157ToolsetLayout VSLayout;158IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem();159if (!findVCToolChainViaCommandLine(*VFS, std::nullopt, std::nullopt,160std::nullopt, VCToolChainPath, VSLayout) &&161!findVCToolChainViaEnvironment(*VFS, VCToolChainPath, VSLayout) &&162!findVCToolChainViaSetupConfig(*VFS, {}, VCToolChainPath, VSLayout) &&163!findVCToolChainViaRegistry(VCToolChainPath, VSLayout))164return make_error<StringError>("Couldn't find msvc toolchain.",165inconvertibleErrorCode());166167std::string UniversalCRTSdkPath;168std::string UCRTVersion;169if (!getUniversalCRTSdkDir(*VFS, std::nullopt, std::nullopt, std::nullopt,170UniversalCRTSdkPath, UCRTVersion))171return make_error<StringError>("Couldn't find universal sdk.",172inconvertibleErrorCode());173174MSVCToolchainPath ToolchainPath;175SmallString<256> VCToolchainLib(VCToolChainPath);176sys::path::append(VCToolchainLib, "lib", "x64");177ToolchainPath.VCToolchainLib = VCToolchainLib;178179SmallString<256> UCRTSdkLib(UniversalCRTSdkPath);180sys::path::append(UCRTSdkLib, "Lib", UCRTVersion, "ucrt", "x64");181ToolchainPath.UCRTSdkLib = UCRTSdkLib;182return ToolchainPath;183}184185186