brintos

brintos / llvm-project-archived public Read only

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