From 7260cdd2e13a3a8970fe106c3d705609029640b5 Mon Sep 17 00:00:00 2001 From: Sunho Kim Date: Thu, 11 Aug 2022 15:27:05 +0900 Subject: [PATCH] [ORC][COFF] Introduce COFFVCRuntimeBootstrapper. Introduces COFFVCRuntimeBootstrapper that loads/initialize vc runtime libraries. In COFF, we *must* jit-link vc runtime libraries as COFF relocation types have no proper way to deal with out-of-reach data symbols ragardless of linking mode. (even dynamic version msvcrt.lib have tons of static data symbols that must be jit-linked) This class tries to load vc runtime library files from msvc installations with an option to override the path. There are some complications when dealing with static version of vc runtimes. First, they need static initializers to be ran that requires COFFPlatform support but orc runtime will not be usable before vc runtimes are fully initialized. (as orc runtime will use msvc stl libraries) COFFPlatform that will be introduced in a following up patch will collect static initializers and run them manually in host before boostrapping itself. So, the user will have to do the following. 1. Create COFFPlatform that addes static initializer collecting passes. 2. LoadVCRuntime 3. InitializeVCRuntime 4. COFFPlatform.bootstrap() Second, the internal crt initialization function had to be reimplemented in orc side. There are other ways of doing this, but this is the simplest implementation that makes platform fully responsible for static initializer. The complication comes from the fact that crt initialization functions (such as acrt_initialize or dllmain_crt_process_attach) actually run all static initializers by traversing from `__xi_a` symbol to `__xi_z`. This requires symbols to be contiguously allocated in sections alphabetically sorted in memory, which is not possible right now and not practical in jit setting. We might ignore emission of `__xi_a` and `__xi_z` symbol and allocate them ourselves, but we have to take extra care after orc runtime boostrap has been done -- as that point orc runtime should be the one running the static initializers. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D130456 --- .../ExecutionEngine/Orc/COFFVCRuntimeSupport.h | 89 ++++++++++ .../ExecutionEngine/Orc/ExecutorProcessControl.h | 21 +++ .../llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h | 5 +- .../llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h | 6 + .../Orc/TargetProcess/TargetExecutionUtils.h | 3 + llvm/lib/ExecutionEngine/Orc/CMakeLists.txt | 2 + .../ExecutionEngine/Orc/COFFVCRuntimeSupport.cpp | 184 +++++++++++++++++++++ .../ExecutionEngine/Orc/ExecutorProcessControl.cpp | 12 ++ .../lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp | 4 + llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp | 21 ++- .../Orc/TargetProcess/OrcRTBootstrap.cpp | 25 +++ .../Orc/TargetProcess/TargetExecutionUtils.cpp | 4 + 12 files changed, 374 insertions(+), 2 deletions(-) create mode 100644 llvm/include/llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h create mode 100644 llvm/lib/ExecutionEngine/Orc/COFFVCRuntimeSupport.cpp diff --git a/llvm/include/llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h b/llvm/include/llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h new file mode 100644 index 0000000..e390471 --- /dev/null +++ b/llvm/include/llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h @@ -0,0 +1,89 @@ +//===----- COFFVCRuntimeSupport.h -- VC runtime support in ORC --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Utilities for loading and initializaing vc runtime in Orc. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_COFFCRUNTIMESUPPORT_H +#define LLVM_EXECUTIONENGINE_ORC_COFFCRUNTIMESUPPORT_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" +#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" +#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" + +#include +#include +#include +#include + +namespace llvm { +namespace orc { + +/// Bootstraps the vc runtime within jitdylibs. +class COFFVCRuntimeBootstrapper { +public: + /// Try to create a COFFVCRuntimeBootstrapper instance. An optional + /// RuntimePath can be given to specify the location of directory that + /// contains all vc runtime library files such as ucrt.lib and msvcrt.lib. If + /// not path was given, it will try to search the MSVC toolchain and Windows + /// SDK installation and use the found library files automatically. + /// + /// Note that depending on the build setting, a different library + /// file must be used. In general, if vc runtime was statically linked to the + /// object file that is to be jit-linked, LoadStaticVCRuntime and + /// InitializeStaticVCRuntime must be used with libcmt.lib, libucrt.lib, + /// libvcruntimelib. If vc runtime was dynamically linked LoadDynamicVCRuntime + /// must be used along with msvcrt.lib, ucrt.lib, vcruntime.lib. + /// + /// More information is on: + /// https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features + static Expected> + Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, + const char *RuntimePath = nullptr); + + /// Adds symbol definitions of static version of msvc runtime libraries. + Expected> + loadStaticVCRuntime(JITDylib &JD, bool DebugVersion = false); + + /// Runs the initializer of static version of msvc runtime libraries. + /// This must be called before calling any functions requiring c runtime (e.g. + /// printf) within the jit session. Note that proper initialization of vc + /// runtime requires ability of running static initializers. Cosider setting + /// up COFFPlatform. + Error initializeStaticVCRuntime(JITDylib &JD); + + /// Adds symbol definitions of dynamic versino of msvc runtie libraries. + Expected> + loadDynamicVCRuntime(JITDylib &JD, bool DebugVersion = false); + +private: + COFFVCRuntimeBootstrapper(ExecutionSession &ES, + ObjectLinkingLayer &ObjLinkingLayer, + const char *RuntimePath); + + ExecutionSession &ES; + ObjectLinkingLayer &ObjLinkingLayer; + std::string RuntimePath; + + struct MSVCToolchainPath { + SmallString<256> VCToolchainLib; + SmallString<256> UCRTSdkLib; + }; + + static Expected getMSVCToolchainPath(); + Error loadVCRuntime(JITDylib &JD, std::vector &ImportedLibraries, + ArrayRef VCLibs, ArrayRef UCRTLibs); +}; + +} // namespace orc +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutorProcessControl.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutorProcessControl.h index 88a2796..20f5c98 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutorProcessControl.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutorProcessControl.h @@ -259,6 +259,15 @@ public: virtual Expected runAsMain(ExecutorAddr MainFnAddr, ArrayRef Args) = 0; + // TODO: move this to ORC runtime. + /// Run function with a int (*)(void) signature. + virtual Expected runAsVoidFunction(ExecutorAddr VoidFnAddr) = 0; + + // TODO: move this to ORC runtime. + /// Run function with a int (*)(int) signature. + virtual Expected runAsIntFunction(ExecutorAddr IntFnAddr, + int Arg) = 0; + /// Run a wrapper function in the executor. The given WFRHandler will be /// called on the result when it is returned. /// @@ -397,6 +406,14 @@ public: llvm_unreachable("Unsupported"); } + Expected runAsVoidFunction(ExecutorAddr VoidFnAddr) override { + llvm_unreachable("Unsupported"); + } + + Expected runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override { + llvm_unreachable("Unsupported"); + } + void callWrapperAsync(ExecutorAddr WrapperFnAddr, IncomingWFRHandler OnComplete, ArrayRef ArgBuffer) override { @@ -434,6 +451,10 @@ public: Expected runAsMain(ExecutorAddr MainFnAddr, ArrayRef Args) override; + Expected runAsVoidFunction(ExecutorAddr VoidFnAddr) override; + + Expected runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override; + void callWrapperAsync(ExecutorAddr WrapperFnAddr, IncomingWFRHandler OnComplete, ArrayRef ArgBuffer) override; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h index 2aedf1e..82d6901 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h @@ -47,6 +47,8 @@ extern const char *RegisterEHFrameSectionWrapperName; extern const char *DeregisterEHFrameSectionWrapperName; extern const char *RunAsMainWrapperName; +extern const char *RunAsVoidFunctionWrapperName; +extern const char *RunAsIntFunctionWrapperName; using SPSSimpleExecutorDylibManagerOpenSignature = shared::SPSExpected(shared::SPSExecutorAddr, shared::SPSString, @@ -81,7 +83,8 @@ using SPSExecutorSharedMemoryMapperServiceReleaseSignature = shared::SPSError( using SPSRunAsMainSignature = int64_t(shared::SPSExecutorAddr, shared::SPSSequence); - +using SPSRunAsVoidFunctionSignature = int32_t(shared::SPSExecutorAddr); +using SPSRunAsIntFunctionSignature = int32_t(shared::SPSExecutorAddr, int32_t); } // end namespace rt } // end namespace orc } // end namespace llvm diff --git a/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h b/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h index bd72e45..25b79be 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h @@ -77,6 +77,10 @@ public: Expected runAsMain(ExecutorAddr MainFnAddr, ArrayRef Args) override; + Expected runAsVoidFunction(ExecutorAddr VoidFnAddr) override; + + Expected runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override; + void callWrapperAsync(ExecutorAddr WrapperFnAddr, IncomingWFRHandler OnComplete, ArrayRef ArgBuffer) override; @@ -129,6 +133,8 @@ private: std::unique_ptr DylibMgr; ExecutorAddr RunAsMainAddr; + ExecutorAddr RunAsVoidFunctionAddr; + ExecutorAddr RunAsIntFunctionAddr; uint64_t NextSeqNo = 0; PendingCallWrapperResultsMap PendingCallWrapperResults; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h index 1d2f6d2..e01bb50 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h @@ -32,6 +32,9 @@ namespace orc { int runAsMain(int (*Main)(int, char *[]), ArrayRef Args, Optional ProgramName = None); +int runAsVoidFunction(int (*Func)(void)); +int runAsIntFunction(int (*Func)(int), int Arg); + } // end namespace orc } // end namespace llvm diff --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt index 5a03102..8b8eaac 100644 --- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt +++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt @@ -3,6 +3,7 @@ if( CMAKE_HOST_UNIX AND HAVE_LIBRT ) endif() add_llvm_component_library(LLVMOrcJIT + COFFVCRuntimeSupport.cpp CompileOnDemandLayer.cpp CompileUtils.cpp Core.cpp @@ -59,6 +60,7 @@ add_llvm_component_library(LLVMOrcJIT Object OrcShared OrcTargetProcess + WindowsDriver MC MCDisassembler Passes diff --git a/llvm/lib/ExecutionEngine/Orc/COFFVCRuntimeSupport.cpp b/llvm/lib/ExecutionEngine/Orc/COFFVCRuntimeSupport.cpp new file mode 100644 index 0000000..f5be80c --- /dev/null +++ b/llvm/lib/ExecutionEngine/Orc/COFFVCRuntimeSupport.cpp @@ -0,0 +1,184 @@ +//===------- COFFVCRuntimeSupport.cpp - VC runtime support in ORC ---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h" + +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" +#include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h" +#include "llvm/Support/VirtualFileSystem.h" +#include "llvm/WindowsDriver/MSVCPaths.h" + +#define DEBUG_TYPE "orc" + +using namespace llvm; +using namespace llvm::orc; +using namespace llvm::orc::shared; + +Expected> +COFFVCRuntimeBootstrapper::Create(ExecutionSession &ES, + ObjectLinkingLayer &ObjLinkingLayer, + const char *RuntimePath) { + return std::unique_ptr( + new COFFVCRuntimeBootstrapper(ES, ObjLinkingLayer, RuntimePath)); +} + +COFFVCRuntimeBootstrapper::COFFVCRuntimeBootstrapper( + ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer, + const char *RuntimePath) + : ES(ES), ObjLinkingLayer(ObjLinkingLayer) { + if (RuntimePath) + this->RuntimePath = RuntimePath; +} + +Expected> +COFFVCRuntimeBootstrapper::loadStaticVCRuntime(JITDylib &JD, + bool DebugVersion) { + StringRef VCLibs[] = {"libvcruntime.lib", "libcmt.lib", "libcpmt.lib"}; + StringRef UCRTLibs[] = {"libucrt.lib"}; + std::vector ImportedLibraries; + if (auto Err = loadVCRuntime(JD, ImportedLibraries, makeArrayRef(VCLibs), + makeArrayRef(UCRTLibs))) + return Err; + return ImportedLibraries; +} + +Expected> +COFFVCRuntimeBootstrapper::loadDynamicVCRuntime(JITDylib &JD, + bool DebugVersion) { + StringRef VCLibs[] = {"vcruntime.lib", "msvcrt.lib", "msvcprt.lib"}; + StringRef UCRTLibs[] = {"ucrt.lib"}; + std::vector ImportedLibraries; + if (auto Err = loadVCRuntime(JD, ImportedLibraries, makeArrayRef(VCLibs), + makeArrayRef(UCRTLibs))) + return Err; + return ImportedLibraries; +} + +Error COFFVCRuntimeBootstrapper::loadVCRuntime( + JITDylib &JD, std::vector &ImportedLibraries, + ArrayRef VCLibs, ArrayRef UCRTLibs) { + MSVCToolchainPath Path; + if (!RuntimePath.empty()) { + Path.UCRTSdkLib = RuntimePath; + Path.VCToolchainLib = RuntimePath; + } else { + auto ToolchainPath = getMSVCToolchainPath(); + if (!ToolchainPath) + return ToolchainPath.takeError(); + Path = *ToolchainPath; + } + LLVM_DEBUG({ + dbgs() << "Using VC toolchain pathes\n"; + dbgs() << " VC toolchain path: " << Path.VCToolchainLib << "\n"; + dbgs() << " UCRT path: " << Path.UCRTSdkLib << "\n"; + }); + + auto LoadLibrary = [&](SmallString<256> LibPath, StringRef LibName) -> Error { + sys::path::append(LibPath, LibName); + + auto G = StaticLibraryDefinitionGenerator::Load(ObjLinkingLayer, + LibPath.c_str()); + if (!G) + return G.takeError(); + + for (auto &Lib : (*G)->getImportedDynamicLibraries()) + ImportedLibraries.push_back(Lib); + + JD.addGenerator(std::move(*G)); + + return Error::success(); + }; + for (auto &Lib : UCRTLibs) + if (auto Err = LoadLibrary(Path.UCRTSdkLib, Lib)) + return Err; + + for (auto &Lib : VCLibs) + if (auto Err = LoadLibrary(Path.VCToolchainLib, Lib)) + return Err; + ImportedLibraries.push_back("ntdll.dll"); + ImportedLibraries.push_back("Kernel32.dll"); + + return Error::success(); +} + +Error COFFVCRuntimeBootstrapper::initializeStaticVCRuntime(JITDylib &JD) { + ExecutorAddr jit_scrt_initialize, jit_scrt_dllmain_before_initialize_c, + jit_scrt_initialize_type_info, + jit_scrt_initialize_default_local_stdio_options; + if (auto Err = lookupAndRecordAddrs( + ES, LookupKind::Static, makeJITDylibSearchOrder(&JD), + {{ES.intern("__scrt_initialize_crt"), &jit_scrt_initialize}, + {ES.intern("__scrt_dllmain_before_initialize_c"), + &jit_scrt_dllmain_before_initialize_c}, + {ES.intern("?__scrt_initialize_type_info@@YAXXZ"), + &jit_scrt_initialize_type_info}, + {ES.intern("__scrt_initialize_default_local_stdio_options"), + &jit_scrt_initialize_default_local_stdio_options}})) + return Err; + + auto RunVoidInitFunc = [&](ExecutorAddr Addr) -> Error { + if (auto Res = ES.getExecutorProcessControl().runAsVoidFunction(Addr)) + return Error::success(); + else + return Res.takeError(); + }; + + auto R = + ES.getExecutorProcessControl().runAsIntFunction(jit_scrt_initialize, 0); + if (!R) + return R.takeError(); + + if (auto Err = RunVoidInitFunc(jit_scrt_dllmain_before_initialize_c)) + return Err; + + if (auto Err = RunVoidInitFunc(jit_scrt_initialize_type_info)) + return Err; + + if (auto Err = + RunVoidInitFunc(jit_scrt_initialize_default_local_stdio_options)) + return Err; + + SymbolAliasMap Alias; + Alias[ES.intern("__run_after_c_init")] = { + ES.intern("__scrt_dllmain_after_initialize_c"), JITSymbolFlags::Exported}; + if (auto Err = JD.define(symbolAliases(Alias))) + return Err; + + return Error::success(); +} + +Expected +COFFVCRuntimeBootstrapper::getMSVCToolchainPath() { + std::string VCToolChainPath; + ToolsetLayout VSLayout; + IntrusiveRefCntPtr VFS = vfs::getRealFileSystem(); + if (!findVCToolChainViaCommandLine(*VFS, None, None, None, VCToolChainPath, + VSLayout) && + !findVCToolChainViaEnvironment(*VFS, VCToolChainPath, VSLayout) && + !findVCToolChainViaSetupConfig(*VFS, VCToolChainPath, VSLayout) && + !findVCToolChainViaRegistry(VCToolChainPath, VSLayout)) + return make_error("Couldn't find msvc toolchain.", + inconvertibleErrorCode()); + + std::string UniversalCRTSdkPath; + std::string UCRTVersion; + if (!getUniversalCRTSdkDir(*VFS, None, None, None, UniversalCRTSdkPath, + UCRTVersion)) + return make_error("Couldn't find universal sdk.", + inconvertibleErrorCode()); + + MSVCToolchainPath ToolchainPath; + SmallString<256> VCToolchainLib(VCToolChainPath); + sys::path::append(VCToolchainLib, "lib", "x64"); + ToolchainPath.VCToolchainLib = VCToolchainLib; + + SmallString<256> UCRTSdkLib(UniversalCRTSdkPath); + sys::path::append(UCRTSdkLib, "Lib", UCRTVersion, "ucrt", "x64"); + ToolchainPath.UCRTSdkLib = UCRTSdkLib; + return ToolchainPath; +} diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp index 412b9f9..8f3bd92 100644 --- a/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ExecutorProcessControl.cpp @@ -121,6 +121,18 @@ SelfExecutorProcessControl::runAsMain(ExecutorAddr MainFnAddr, return orc::runAsMain(MainFnAddr.toPtr(), Args); } +Expected +SelfExecutorProcessControl::runAsVoidFunction(ExecutorAddr VoidFnAddr) { + using VoidTy = int (*)(); + return orc::runAsVoidFunction(VoidFnAddr.toPtr()); +} + +Expected +SelfExecutorProcessControl::runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) { + using IntTy = int (*)(int); + return orc::runAsIntFunction(IntFnAddr.toPtr(), Arg); +} + void SelfExecutorProcessControl::callWrapperAsync(ExecutorAddr WrapperFnAddr, IncomingWFRHandler SendResult, ArrayRef ArgBuffer) { diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp index dfdd846..86e31c5 100644 --- a/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp @@ -56,6 +56,10 @@ const char *DeregisterEHFrameSectionWrapperName = "__llvm_orc_bootstrap_deregister_ehframe_section_wrapper"; const char *RunAsMainWrapperName = "__llvm_orc_bootstrap_run_as_main_wrapper"; +const char *RunAsVoidFunctionWrapperName = + "__llvm_orc_bootstrap_run_as_void_function_wrapper"; +const char *RunAsIntFunctionWrapperName = + "__llvm_orc_bootstrap_run_as_int_function_wrapper"; } // end namespace rt } // end namespace orc diff --git a/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp b/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp index 47364a9..c69df4f 100644 --- a/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp +++ b/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp @@ -54,6 +54,23 @@ Expected SimpleRemoteEPC::runAsMain(ExecutorAddr MainFnAddr, return Result; } +Expected SimpleRemoteEPC::runAsVoidFunction(ExecutorAddr VoidFnAddr) { + int32_t Result = 0; + if (auto Err = callSPSWrapper( + RunAsVoidFunctionAddr, Result, ExecutorAddr(VoidFnAddr))) + return std::move(Err); + return Result; +} + +Expected SimpleRemoteEPC::runAsIntFunction(ExecutorAddr IntFnAddr, + int Arg) { + int32_t Result = 0; + if (auto Err = callSPSWrapper( + RunAsIntFunctionAddr, Result, ExecutorAddr(IntFnAddr), Arg)) + return std::move(Err); + return Result; +} + void SimpleRemoteEPC::callWrapperAsync(ExecutorAddr WrapperFnAddr, IncomingWFRHandler OnComplete, ArrayRef ArgBuffer) { @@ -312,7 +329,9 @@ Error SimpleRemoteEPC::setup(Setup S) { if (auto Err = getBootstrapSymbols( {{JDI.JITDispatchContext, ExecutorSessionObjectName}, {JDI.JITDispatchFunction, DispatchFnName}, - {RunAsMainAddr, rt::RunAsMainWrapperName}})) + {RunAsMainAddr, rt::RunAsMainWrapperName}, + {RunAsVoidFunctionAddr, rt::RunAsVoidFunctionWrapperName}, + {RunAsIntFunctionAddr, rt::RunAsIntFunctionWrapperName}})) return Err; if (auto DM = diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp index 909d47d..b388779 100644 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.cpp @@ -56,6 +56,27 @@ runAsMainWrapper(const char *ArgData, size_t ArgSize) { .release(); } +static llvm::orc::shared::CWrapperFunctionResult +runAsVoidFunctionWrapper(const char *ArgData, size_t ArgSize) { + return WrapperFunction::handle( + ArgData, ArgSize, + [](ExecutorAddr MainAddr) -> int32_t { + return runAsVoidFunction(MainAddr.toPtr()); + }) + .release(); +} + +static llvm::orc::shared::CWrapperFunctionResult +runAsIntFunctionWrapper(const char *ArgData, size_t ArgSize) { + return WrapperFunction::handle( + ArgData, ArgSize, + [](ExecutorAddr MainAddr, int32_t Arg) -> int32_t { + return runAsIntFunction(MainAddr.toPtr(), + Arg); + }) + .release(); +} + void addTo(StringMap &M) { M[rt::MemoryWriteUInt8sWrapperName] = ExecutorAddr::fromPtr( &writeUIntsWrapper &M) { M[rt::DeregisterEHFrameSectionWrapperName] = ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper); M[rt::RunAsMainWrapperName] = ExecutorAddr::fromPtr(&runAsMainWrapper); + M[rt::RunAsVoidFunctionWrapperName] = + ExecutorAddr::fromPtr(&runAsVoidFunctionWrapper); + M[rt::RunAsIntFunctionWrapperName] = + ExecutorAddr::fromPtr(&runAsIntFunctionWrapper); } } // end namespace rt_bootstrap diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.cpp index a8e6c04..b76b745c 100644 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.cpp @@ -39,5 +39,9 @@ int runAsMain(int (*Main)(int, char *[]), ArrayRef Args, return Main(Args.size() + !!ProgramName, ArgV.data()); } +int runAsVoidFunction(int (*Func)(void)) { return Func(); } + +int runAsIntFunction(int (*Func)(int), int Arg) { return Func(Arg); } + } // End namespace orc. } // End namespace llvm. -- 2.7.4