<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Feb 25, 2020 at 9:15 AM Lang Hames via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto">Hi Eric,<div><br></div><div>I think this leak is expected (i.e. that cache might not be cleared until process termination), but I will need to talk to the ObjC runtime folks to confirm.</div></div></blockquote><div><br></div><div>Any word/follow up on this?<br><br>In theory a permanently accessible object until process termination should not be classified as a leak by Leak Sanitizer (eg, this program "int *x = new int(3); int main() { }" doesn't contain a leak, as such)... so something else at work here?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div><br></div><div>Any chance you could test a workaround for me in the mean time? I think if we replace the current run line,</div><div><br></div><div>RUN: lli -jit-kind=orc-lazy %s</div><div><br></div><div>with</div><div><br></div><div>RUN: ASAN_OPTIONS=detect_leaks=0 lli -jit-kind=orc-lazy %s</div><div><br></div><div>That should allow us to at least keep running asan on the test. If that doesn’t work we can just disable the test entirely when asan is enabled by adding</div><div><br></div><div>; UNSUPPORTED: asan</div><div><br></div><div>at the top.</div><div><br></div><div>I’d test these myself but my asan build doesn’t seem to have leak checking enabled, so I wasn’t able to reproduce this failure locally.</div><div><br></div><div>Regards,</div><div>Lang.</div><div><br></div><div><div dir="ltr"><blockquote type="cite">On Feb 24, 2020, at 1:44 PM, Lang Hames <<a href="mailto:lhames@gmail.com" target="_blank">lhames@gmail.com</a>> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr">Hi Eric,<div><br></div><div>Thanks for letting me know! I’ll take a look and see if I can figure this out.</div><div><br></div><div>Regards,</div><div>Lang.<br><br><div dir="ltr">Sent from my iPad</div><div dir="ltr"><br><blockquote type="cite">On Feb 24, 2020, at 10:29 AM, Erik Pilkington <<a href="mailto:erik.pilkington@gmail.com" target="_blank">erik.pilkington@gmail.com</a>> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr">Hi Lang,<div><br></div><div>It looks like a test you added in this commit is failing on macOS: <a href="http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan/6977" target="_blank">http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan/6977</a></div><div><br></div><div><div>Can you please take a look?</div><div><br></div><div>Thanks!</div><div>Erik<div><blockquote type="cite"></blockquote></div></div></div><div><br></div><div><pre style="color:rgb(0,0,0);white-space:pre-wrap">******************** TEST 'LLVM :: ExecutionEngine/OrcLazy/objc-minimal.ll' FAILED ********************
Script:
--
: 'RUN: at line 2';   /Users/buildslave/jenkins/workspace/clang-stage2-cmake-RgSan/clang-build/bin/lli -jit-kind=orc-lazy /Users/buildslave/jenkins/workspace/clang-stage2-cmake-RgSan/llvm-project/llvm/test/ExecutionEngine/OrcLazy/objc-minimal.ll
--
Exit Code: 1

Command Output (stderr):
--

=================================================================
==96779==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 80 byte(s) in 1 object(s) allocated from:
    #0 0x1127fbef2 in wrap_calloc+0xa2 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x45ef2)
    #1 0x7fff5addac5d in allocateBuckets(unsigned int)+0x1d (libobjc.A.dylib:x86_64h+0x9c5d)
    #2 0x7fff5addabec in cache_t::reallocate(unsigned int, unsigned int)+0x2a (libobjc.A.dylib:x86_64h+0x9bec)
    #3 0x7fff5adda3a8 in cache_fill+0xc2 (libobjc.A.dylib:x86_64h+0x93a8)
    #4 0x7fff5add9b94 in lookUpImpOrForward+0x269 (libobjc.A.dylib:x86_64h+0x8b94)
    #5 0x7fff5add9493 in _objc_msgSend_uncached+0x43 (libobjc.A.dylib:x86_64h+0x8493)
    #6 0x1166f702a  (<unknown module>)
    #7 0x10a89cd22 in runOrcLazyJIT(char const*) lli.cpp:991
    #8 0x10a890b79 in main lli.cpp:409
    #9 0x7fff5beb5084 in start+0x0 (libdyld.dylib:x86_64+0x17084)

Direct leak of 80 byte(s) in 1 object(s) allocated from:
    #0 0x1127fbef2 in wrap_calloc+0xa2 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x45ef2)
    #1 0x7fff5addac5d in allocateBuckets(unsigned int)+0x1d (libobjc.A.dylib:x86_64h+0x9c5d)
    #2 0x7fff5addabec in cache_t::reallocate(unsigned int, unsigned int)+0x2a (libobjc.A.dylib:x86_64h+0x9bec)
    #3 0x7fff5adda3a8 in cache_fill+0xc2 (libobjc.A.dylib:x86_64h+0x93a8)
    #4 0x7fff5add9b94 in lookUpImpOrForward+0x269 (libobjc.A.dylib:x86_64h+0x8b94)
    #5 0x7fff5add9493 in _objc_msgSend_uncached+0x43 (libobjc.A.dylib:x86_64h+0x8493)
    #6 0x1166f701b  (<unknown module>)
    #7 0x10a89cd22 in runOrcLazyJIT(char const*) lli.cpp:991
    #8 0x10a890b79 in main lli.cpp:409
    #9 0x7fff5beb5084 in start+0x0 (libdyld.dylib:x86_64+0x17084)

Direct leak of 64 byte(s) in 1 object(s) allocated from:
    #0 0x1127fbef2 in wrap_calloc+0xa2 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x45ef2)
    #1 0x7fff5add6510 in realizeClass(objc_class*)+0x4c (libobjc.A.dylib:x86_64h+0x5510)
    #2 0x7fff5add65e2 in realizeClass(objc_class*)+0x11e (libobjc.A.dylib:x86_64h+0x55e2)
    #3 0x7fff5adee3f5 in objc_readClassPair+0x76 (libobjc.A.dylib:x86_64h+0x1d3f5)
    #4 0x10be4620c in llvm::orc::MachOJITDylibInitializers::registerObjCClasses() const MachOPlatform.cpp:133
    #5 0x10be246a7 in (anonymous namespace)::MachOPlatformSupport::initialize(llvm::orc::JITDylib&) LLJIT.cpp:525
    #6 0x10a8a73f7 in llvm::orc::LLJIT::initialize(llvm::orc::JITDylib&) LLJIT.h:141
    #7 0x10a89c514 in runOrcLazyJIT(char const*) lli.cpp:975
    #8 0x10a890b79 in main lli.cpp:409
    #9 0x7fff5beb5084 in start+0x0 (libdyld.dylib:x86_64+0x17084)

Direct leak of 64 byte(s) in 1 object(s) allocated from:
    #0 0x1127fbef2 in wrap_calloc+0xa2 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x45ef2)
    #1 0x7fff5add6510 in realizeClass(objc_class*)+0x4c (libobjc.A.dylib:x86_64h+0x5510)
    #2 0x7fff5adee3f5 in objc_readClassPair+0x76 (libobjc.A.dylib:x86_64h+0x1d3f5)
    #3 0x10be4620c in llvm::orc::MachOJITDylibInitializers::registerObjCClasses() const MachOPlatform.cpp:133
    #4 0x10be246a7 in (anonymous namespace)::MachOPlatformSupport::initialize(llvm::orc::JITDylib&) LLJIT.cpp:525
    #5 0x10a8a73f7 in llvm::orc::LLJIT::initialize(llvm::orc::JITDylib&) LLJIT.h:141
    #6 0x10a89c514 in runOrcLazyJIT(char const*) lli.cpp:975
    #7 0x10a890b79 in main lli.cpp:409
    #8 0x7fff5beb5084 in start+0x0 (libdyld.dylib:x86_64+0x17084)

Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x1127fbef2 in wrap_calloc+0xa2 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x45ef2)
    #1 0x7fff5add883d in class_createInstance+0x52 (libobjc.A.dylib:x86_64h+0x783d)
    #2 0x7fff5addc595 in _objc_rootAlloc+0x2c (libobjc.A.dylib:x86_64h+0xb595)
    #3 0x1166f701b  (<unknown module>)
    #4 0x10a89cd22 in runOrcLazyJIT(char const*) lli.cpp:991
    #5 0x10a890b79 in main lli.cpp:409
    #6 0x7fff5beb5084 in start+0x0 (libdyld.dylib:x86_64+0x17084)

SUMMARY: AddressSanitizer: 304 byte(s) leaked in 5 allocation(s)
</pre></div><div><div><blockquote type="cite"><div>On Feb 19, 2020, at 2:03 PM, Lang Hames via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:</div><br><div><div><br>Author: Lang Hames<br>Date: 2020-02-19T13:59:32-08:00<br>New Revision: 85fb997659b55101b58e3545733e581bf4ed9cf2<br><br>URL: <a href="https://github.com/llvm/llvm-project/commit/85fb997659b55101b58e3545733e581bf4ed9cf2" target="_blank">https://github.com/llvm/llvm-project/commit/85fb997659b55101b58e3545733e581bf4ed9cf2</a><br>DIFF: <a href="https://github.com/llvm/llvm-project/commit/85fb997659b55101b58e3545733e581bf4ed9cf2.diff" target="_blank">https://github.com/llvm/llvm-project/commit/85fb997659b55101b58e3545733e581bf4ed9cf2.diff</a><br><br>LOG: [ORC] Add generic initializer/deinitializer support.<br><br>Initializers and deinitializers are used to implement C++ static constructors<br>and destructors, runtime registration for some languages (e.g. with the<br>Objective-C runtime for Objective-C/C++ code) and other tasks that would<br>typically be performed when a shared-object/dylib is loaded or unloaded by a<br>statically compiled program.<br><br>MCJIT and ORC have historically provided limited support for discovering and<br>running initializers/deinitializers by scanning the llvm.global_ctors and<br>llvm.global_dtors variables and recording the functions to be run. This approach<br>suffers from several drawbacks: (1) It only works for IR inputs, not for object<br>files (including cached JIT'd objects). (2) It only works for initializers<br>described by llvm.global_ctors and llvm.global_dtors, however not all<br>initializers are described in this way (Objective-C, for example, describes<br>initializers via specially named metadata sections). (3) To make the<br>initializer/deinitializer functions described by llvm.global_ctors and<br>llvm.global_dtors searchable they must be promoted to extern linkage, polluting<br>the JIT symbol table (extra care must be taken to ensure this promotion does<br>not result in symbol name clashes).<br><br>This patch introduces several interdependent changes to ORCv2 to support the<br>construction of new initialization schemes, and includes an implementation of a<br>backwards-compatible llvm.global_ctor/llvm.global_dtor scanning scheme, and a<br>MachO specific scheme that handles Objective-C runtime registration (if the<br>Objective-C runtime is available) enabling execution of LLVM IR compiled from<br>Objective-C and Swift.<br><br>The major changes included in this patch are:<br><br>(1) The MaterializationUnit and MaterializationResponsibility classes are<br>extended to describe an optional "initializer" symbol for the module (see the<br>getInitializerSymbol method on each class). The presence or absence of this<br>symbol indicates whether the module contains any initializers or<br>deinitializers. The initializer symbol otherwise behaves like any other:<br>searching for it triggers materialization.<br><br>(2) A new Platform interface is introduced in llvm/ExecutionEngine/Orc/Core.h<br>which provides the following callback interface:<br><br>  - Error setupJITDylib(JITDylib &JD): Can be used to install standard symbols<br>    in JITDylibs upon creation. E.g. __dso_handle.<br><br>  - Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU): Generally<br>    used to record initializer symbols.<br><br>  - Error notifyRemoving(JITDylib &JD, VModuleKey K): Used to notify a platform<br>    that a module is being removed.<br><br>  Platform implementations can use these callbacks to track outstanding<br>initializers and implement a platform-specific approach for executing them. For<br>example, the MachOPlatform installs a plugin in the JIT linker to scan for both<br>__mod_inits sections (for C++ static constructors) and ObjC metadata sections.<br>If discovered, these are processed in the usual platform order: Objective-C<br>registration is carried out first, then static initializers are executed,<br>ensuring that calls to Objective-C from static initializers will be safe.<br><br>This patch updates LLJIT to use the new scheme for initialization. Two<br>LLJIT::PlatformSupport classes are implemented: A GenericIR platform and a MachO<br>platform. The GenericIR platform implements a modified version of the previous<br>llvm.global-ctor scraping scheme to provide support for Windows and<br>Linux. LLJIT's MachO platform uses the MachOPlatform class to provide MachO<br>specific initialization as described above.<br><br>Reviewers: sgraenitz, dblaikie<br><br>Subscribers: mgorny, hiraditya, mgrang, ributzka, llvm-commits<br><br>Tags: #llvm<br><br>Differential Revision: <a href="https://reviews.llvm.org/D74300" target="_blank">https://reviews.llvm.org/D74300</a><br><br>Added: <br>    llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h<br>    llvm/include/llvm/ExecutionEngine/Orc/Mangling.h<br>    llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp<br>    llvm/lib/ExecutionEngine/Orc/Mangling.cpp<br>    llvm/test/ExecutionEngine/OrcLazy/objc-minimal.ll<br><br>Modified: <br>    llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h<br>    llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h<br>    llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h<br>    llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>    llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h<br>    llvm/include/llvm/ExecutionEngine/Orc/Core.h<br>    llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h<br>    llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h<br>    llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h<br>    llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h<br>    llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h<br>    llvm/include/llvm/ExecutionEngine/Orc/Layer.h<br>    llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h<br>    llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h<br>    llvm/lib/ExecutionEngine/Orc/CMakeLists.txt<br>    llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp<br>    llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp<br>    llvm/lib/ExecutionEngine/Orc/Core.cpp<br>    llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp<br>    llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp<br>    llvm/lib/ExecutionEngine/Orc/LLJIT.cpp<br>    llvm/lib/ExecutionEngine/Orc/Layer.cpp<br>    llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp<br>    llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp<br>    llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp<br>    llvm/tools/lli/lli.cpp<br>    llvm/tools/llvm-jitlink/llvm-jitlink.cpp<br>    llvm/tools/llvm-jitlink/llvm-jitlink.h<br>    llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp<br>    llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h<br>    llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp<br><br>Removed: <br><br><br><br>################################################################################<br>diff  --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h<br>index b7404baf1ff0..adb6be436660 100644<br>--- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h<br>+++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter1/KaleidoscopeJIT.h<br>@@ -49,7 +49,7 @@ class KaleidoscopeJIT {<br>                      std::make_unique<ConcurrentIRCompiler>(std::move(JTMB))),<br>         DL(std::move(DL)), Mangle(ES, this->DL),<br>         Ctx(std::make_unique<LLVMContext>()),<br>-        MainJD(ES.createJITDylib("<main>")) {<br>+        MainJD(ES.createBareJITDylib("<main>")) {<br>     MainJD.addGenerator(<br>         cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(<br>             DL.getGlobalPrefix())));<br><br>diff  --git a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h<br>index efb19349e3e1..28649ffe4910 100644<br>--- a/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h<br>+++ b/llvm/examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h<br>@@ -55,7 +55,7 @@ class KaleidoscopeJIT {<br>                      std::make_unique<ConcurrentIRCompiler>(std::move(JTMB))),<br>         OptimizeLayer(ES, CompileLayer, optimizeModule), DL(std::move(DL)),<br>         Mangle(ES, this->DL), Ctx(std::make_unique<LLVMContext>()),<br>-        MainJD(ES.createJITDylib("<main>")) {<br>+        MainJD(ES.createBareJITDylib("<main>")) {<br>     MainJD.addGenerator(<br>         cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(<br>             DL.getGlobalPrefix())));<br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h<br>index 1a8f5cacbcd4..d673a89386da 100644<br>--- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h<br>+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h<br>@@ -488,6 +488,8 @@ class Symbol {<br><br>   /// Set the visibility for this Symbol.<br>   void setScope(Scope S) {<br>+    assert((!Name.empty() || S == Scope::Local) &&<br>+           "Can not set anonymous symbol to non-local scope");<br>     assert((S == Scope::Default || Base->isDefined() || Base->isAbsolute()) &&<br>            "Invalid visibility for symbol type");<br>     this->S = static_cast<uint8_t>(S);<br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>index 65295f97e2c6..ef251ac302df 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>@@ -94,6 +94,7 @@ class CompileOnDemandLayer : public IRLayer {<br><br>   /// Sets the ImplSymbolMap<br>   void setImplMap(ImplSymbolMap *Imp);<br>+<br>   /// Emits the given module. This should not be called by clients: it will be<br>   /// called by the JIT when a definition added via the add method is requested.<br>   void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;<br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h<br>index 218afda1b546..8376d163d57a 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h<br>@@ -30,7 +30,7 @@ namespace orc {<br><br> class JITTargetMachineBuilder;<br><br>-IRMaterializationUnit::ManglingOptions<br>+IRSymbolMapper::ManglingOptions<br> irManglingOptionsFromTargetOptions(const TargetOptions &Opts);<br><br> /// Simple compile functor: Takes a single IR module and returns an ObjectFile.<br>@@ -52,7 +52,7 @@ class SimpleCompiler : public IRCompileLayer::IRCompiler {<br>   Expected<CompileResult> operator()(Module &M) override;<br><br> private:<br>-  IRMaterializationUnit::ManglingOptions<br>+  IRSymbolMapper::ManglingOptions<br>   manglingOptionsForTargetMachine(const TargetMachine &TM);<br><br>   CompileResult tryToLoadFromObjectCache(const Module &M);<br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h<br>index 1a55801b9d87..94600f2286b8 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h<br>@@ -14,11 +14,11 @@<br> #define LLVM_EXECUTIONENGINE_ORC_CORE_H<br><br> #include "llvm/ADT/BitmaskEnum.h"<br>+#include "llvm/ADT/DenseSet.h"<br> #include "llvm/ADT/FunctionExtras.h"<br> #include "llvm/ExecutionEngine/JITSymbol.h"<br> #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"<br> #include "llvm/ExecutionEngine/OrcV1Deprecation.h"<br>-#include "llvm/IR/Module.h"<br> #include "llvm/Support/Debug.h"<br><br> #include <memory><br>@@ -456,6 +456,11 @@ class MaterializationResponsibility {<br>   /// before using.<br>   const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }<br><br>+  /// Returns the initialization pseudo-symbol, if any. This symbol will also<br>+  /// be present in the SymbolFlagsMap for this MaterializationResponsibility<br>+  /// object.<br>+  const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; }<br>+<br>   /// Returns the names of any symbols covered by this<br>   /// MaterializationResponsibility object that have queries pending. This<br>   /// information can be used to return responsibility for unrequested symbols<br>@@ -532,10 +537,15 @@ class MaterializationResponsibility {<br>   /// Create a MaterializationResponsibility for the given JITDylib and<br>   ///        initial symbols.<br>   MaterializationResponsibility(JITDylib &JD, SymbolFlagsMap SymbolFlags,<br>-                                VModuleKey K);<br>+                                SymbolStringPtr InitSymbol, VModuleKey K)<br>+      : JD(JD), SymbolFlags(std::move(SymbolFlags)),<br>+        InitSymbol(std::move(InitSymbol)), K(std::move(K)) {<br>+    assert(!this->SymbolFlags.empty() && "Materializing nothing?");<br>+  }<br><br>   JITDylib &JD;<br>   SymbolFlagsMap SymbolFlags;<br>+  SymbolStringPtr InitSymbol;<br>   VModuleKey K;<br> };<br><br>@@ -549,8 +559,13 @@ class MaterializationResponsibility {<br> /// stronger definition is added or already present.<br> class MaterializationUnit {<br> public:<br>-  MaterializationUnit(SymbolFlagsMap InitalSymbolFlags, VModuleKey K)<br>-      : SymbolFlags(std::move(InitalSymbolFlags)), K(std::move(K)) {}<br>+  MaterializationUnit(SymbolFlagsMap InitalSymbolFlags,<br>+                      SymbolStringPtr InitSymbol, VModuleKey K)<br>+      : SymbolFlags(std::move(InitalSymbolFlags)),<br>+        InitSymbol(std::move(InitSymbol)), K(std::move(K)) {<br>+    assert((!this->InitSymbol || this->SymbolFlags.count(this->InitSymbol)) &&<br>+           "If set, InitSymbol should appear in InitialSymbolFlags map");<br>+  }<br><br>   virtual ~MaterializationUnit() {}<br><br>@@ -561,12 +576,15 @@ class MaterializationUnit {<br>   /// Return the set of symbols that this source provides.<br>   const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }<br><br>+  /// Returns the initialization symbol for this MaterializationUnit (if any).<br>+  const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; }<br>+<br>   /// Called by materialization dispatchers (see<br>   /// ExecutionSession::DispatchMaterializationFunction) to trigger<br>   /// materialization of this MaterializationUnit.<br>   void doMaterialize(JITDylib &JD) {<br>-    materialize(MaterializationResponsibility(JD, std::move(SymbolFlags),<br>-                                              std::move(K)));<br>+    materialize(MaterializationResponsibility(<br>+        JD, std::move(SymbolFlags), std::move(InitSymbol), std::move(K)));<br>   }<br><br>   /// Called by JITDylibs to notify MaterializationUnits that the given symbol<br>@@ -578,6 +596,7 @@ class MaterializationUnit {<br><br> protected:<br>   SymbolFlagsMap SymbolFlags;<br>+  SymbolStringPtr InitSymbol;<br>   VModuleKey K;<br><br> private:<br>@@ -774,6 +793,7 @@ class AsynchronousSymbolQuery {<br> class JITDylib {<br>   friend class AsynchronousSymbolQuery;<br>   friend class ExecutionSession;<br>+  friend class Platform;<br>   friend class MaterializationResponsibility;<br> public:<br>   /// Definition generators can be attached to JITDylibs to generate new<br>@@ -1054,6 +1074,35 @@ class JITDylib {<br>   JITDylibSearchOrder SearchOrder;<br> };<br><br>+/// Platforms set up standard symbols and mediate interactions between dynamic<br>+/// initializers (e.g. C++ static constructors) and ExecutionSession state.<br>+/// Note that Platforms do not automatically run initializers: clients are still<br>+/// responsible for doing this.<br>+class Platform {<br>+public:<br>+  virtual ~Platform();<br>+<br>+  /// This method will be called outside the session lock each time a JITDylib<br>+  /// is created (unless it is created with EmptyJITDylib set) to allow the<br>+  /// Platform to install any JITDylib specific standard symbols (e.g<br>+  /// __dso_handle).<br>+  virtual Error setupJITDylib(JITDylib &JD) = 0;<br>+<br>+  /// This method will be called under the ExecutionSession lock each time a<br>+  /// MaterializationUnit is added to a JITDylib.<br>+  virtual Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) = 0;<br>+<br>+  /// This method will be called under the ExecutionSession lock when a<br>+  /// VModuleKey is removed.<br>+  virtual Error notifyRemoving(JITDylib &JD, VModuleKey K) = 0;<br>+<br>+  /// A utility function for looking up initializer symbols. Performs a blocking<br>+  /// lookup for the given symbols in each of the given JITDylibs.<br>+  static Expected<DenseMap<JITDylib *, SymbolMap>><br>+  lookupInitSymbols(ExecutionSession &ES,<br>+                    const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms);<br>+};<br>+<br> /// An ExecutionSession represents a running JIT program.<br> class ExecutionSession {<br>   // FIXME: Remove this when we remove the old ORC layers.<br>@@ -1078,6 +1127,13 @@ class ExecutionSession {<br>   /// Returns a shared_ptr to the SymbolStringPool for this ExecutionSession.<br>   std::shared_ptr<SymbolStringPool> getSymbolStringPool() const { return SSP; }<br><br>+  /// Set the Platform for this ExecutionSession.<br>+  void setPlatform(std::unique_ptr<Platform> P) { this->P = std::move(P); }<br>+<br>+  /// Get the Platform for this session.<br>+  /// Will return null if no Platform has been set for this ExecutionSession.<br>+  Platform *getPlatform() { return P.get(); }<br>+<br>   /// Run the given lambda with the session mutex locked.<br>   template <typename Func> decltype(auto) runSessionLocked(Func &&F) {<br>     std::lock_guard<std::recursive_mutex> Lock(SessionMutex);<br>@@ -1088,12 +1144,26 @@ class ExecutionSession {<br>   /// Ownership of JITDylib remains within Execution Session<br>   JITDylib *getJITDylibByName(StringRef Name);<br><br>+  /// Add a new bare JITDylib to this ExecutionSession.<br>+  ///<br>+  /// The JITDylib Name is required to be unique. Clients should verify that<br>+  /// names are not being re-used (E.g. by calling getJITDylibByName) if names<br>+  /// are based on user input.<br>+  ///<br>+  /// This call does not install any library code or symbols into the newly<br>+  /// created JITDylib. The client is responsible for all configuration.<br>+  JITDylib &createBareJITDylib(std::string Name);<br>+<br>   /// Add a new JITDylib to this ExecutionSession.<br>   ///<br>   /// The JITDylib Name is required to be unique. Clients should verify that<br>   /// names are not being re-used (e.g. by calling getJITDylibByName) if names<br>   /// are based on user input.<br>-  JITDylib &createJITDylib(std::string Name);<br>+  ///<br>+  /// If a Platform is attached then Platform::setupJITDylib will be called to<br>+  /// install standard platform symbols (e.g. standard library interposes).<br>+  /// If no Platform is attached this call is equivalent to createBareJITDylib.<br>+  Expected<JITDylib &> createJITDylib(std::string Name);<br><br>   /// Allocate a module key for a new module to add to the JIT.<br>   VModuleKey allocateVModule() {<br>@@ -1177,20 +1247,23 @@ class ExecutionSession {<br>   /// Convenience version of blocking lookup.<br>   /// Searches each of the JITDylibs in the search order in turn for the given<br>   /// symbol.<br>-  Expected<JITEvaluatedSymbol> lookup(const JITDylibSearchOrder &SearchOrder,<br>-                                      SymbolStringPtr Symbol);<br>+  Expected<JITEvaluatedSymbol><br>+  lookup(const JITDylibSearchOrder &SearchOrder, SymbolStringPtr Symbol,<br>+         SymbolState RequiredState = SymbolState::Ready);<br><br>   /// Convenience version of blocking lookup.<br>   /// Searches each of the JITDylibs in the search order in turn for the given<br>   /// symbol. The search will not find non-exported symbols.<br>-  Expected<JITEvaluatedSymbol> lookup(ArrayRef<JITDylib *> SearchOrder,<br>-                                      SymbolStringPtr Symbol);<br>+  Expected<JITEvaluatedSymbol><br>+  lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Symbol,<br>+         SymbolState RequiredState = SymbolState::Ready);<br><br>   /// Convenience version of blocking lookup.<br>   /// Searches each of the JITDylibs in the search order in turn for the given<br>   /// symbol. The search will not find non-exported symbols.<br>-  Expected<JITEvaluatedSymbol> lookup(ArrayRef<JITDylib *> SearchOrder,<br>-                                      StringRef Symbol);<br>+  Expected<JITEvaluatedSymbol><br>+  lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Symbol,<br>+         SymbolState RequiredState = SymbolState::Ready);<br><br>   /// Materialize the given unit.<br>   void dispatchMaterialization(JITDylib &JD,<br>@@ -1221,6 +1294,7 @@ class ExecutionSession {<br><br>   mutable std::recursive_mutex SessionMutex;<br>   std::shared_ptr<SymbolStringPool> SSP;<br>+  std::unique_ptr<Platform> P;<br>   VModuleKey LastKey = 0;<br>   ErrorReporter ReportError = logErrorsToStdErr;<br>   DispatchMaterializationFunction DispatchMaterialization =<br>@@ -1256,6 +1330,11 @@ Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU) {<br>     if (auto Err = defineImpl(*MU))<br>       return Err;<br><br>+    if (auto *P = ES.getPlatform()) {<br>+      if (auto Err = P->notifyAdding(*this, *MU))<br>+        return Err;<br>+    }<br>+<br>     /// defineImpl succeeded.<br>     auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));<br>     for (auto &KV : UMI->MU->getSymbols())<br>@@ -1273,6 +1352,11 @@ Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU) {<br>     if (auto Err = defineImpl(*MU))<br>       return Err;<br><br>+    if (auto *P = ES.getPlatform()) {<br>+      if (auto Err = P->notifyAdding(*this, *MU))<br>+        return Err;<br>+    }<br>+<br>     /// defineImpl succeeded.<br>     auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));<br>     for (auto &KV : UMI->MU->getSymbols())<br>@@ -1305,18 +1389,6 @@ class ReexportsGenerator : public JITDylib::DefinitionGenerator {<br>   SymbolPredicate Allow;<br> };<br><br>-/// Mangles symbol names then uniques them in the context of an<br>-/// ExecutionSession.<br>-class MangleAndInterner {<br>-public:<br>-  MangleAndInterner(ExecutionSession &ES, const DataLayout &DL);<br>-  SymbolStringPtr operator()(StringRef Name);<br>-<br>-private:<br>-  ExecutionSession &ES;<br>-  const DataLayout &DL;<br>-};<br>-<br> } // End namespace orc<br> } // End namespace llvm<br><br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h<br>index f7255c5af845..49ab0d628b0b 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h<br>@@ -17,6 +17,7 @@<br> #include "llvm/ADT/iterator_range.h"<br> #include "llvm/ExecutionEngine/JITSymbol.h"<br> #include "llvm/ExecutionEngine/Orc/Core.h"<br>+#include "llvm/ExecutionEngine/Orc/Mangling.h"<br> #include "llvm/ExecutionEngine/Orc/OrcError.h"<br> #include "llvm/ExecutionEngine/RuntimeDyld.h"<br> #include "llvm/Object/Archive.h"<br>@@ -104,6 +105,53 @@ iterator_range<CtorDtorIterator> getConstructors(const Module &M);<br> ///        array.<br> iterator_range<CtorDtorIterator> getDestructors(const Module &M);<br><br>+/// This iterator provides a convenient way to iterate over GlobalValues that<br>+/// have initialization effects.<br>+class StaticInitGVIterator {<br>+public:<br>+  StaticInitGVIterator() = default;<br>+<br>+  StaticInitGVIterator(Module &M)<br>+      : I(M.global_values().begin()), E(M.global_values().end()),<br>+        ObjFmt(Triple(M.getTargetTriple()).getObjectFormat()) {<br>+    if (I != E) {<br>+      if (!isStaticInitGlobal(*I))<br>+        moveToNextStaticInitGlobal();<br>+    } else<br>+      I = E = Module::global_value_iterator();<br>+  }<br>+<br>+  bool operator==(const StaticInitGVIterator &O) const { return I == O.I; }<br>+  bool operator!=(const StaticInitGVIterator &O) const { return I != O.I; }<br>+<br>+  StaticInitGVIterator &operator++() {<br>+    assert(I != E && "Increment past end of range");<br>+    moveToNextStaticInitGlobal();<br>+    return *this;<br>+  }<br>+<br>+  GlobalValue &operator*() { return *I; }<br>+<br>+private:<br>+  bool isStaticInitGlobal(GlobalValue &GV);<br>+  void moveToNextStaticInitGlobal() {<br>+    ++I;<br>+    while (I != E && !isStaticInitGlobal(*I))<br>+      ++I;<br>+    if (I == E)<br>+      I = E = Module::global_value_iterator();<br>+  }<br>+<br>+  Module::global_value_iterator I, E;<br>+  Triple::ObjectFormatType ObjFmt;<br>+};<br>+<br>+/// Create an iterator range over the GlobalValues that contribute to static<br>+/// initialization.<br>+inline iterator_range<StaticInitGVIterator> getStaticInitGVs(Module &M) {<br>+  return make_range(StaticInitGVIterator(M), StaticInitGVIterator());<br>+}<br>+<br> /// Convenience class for recording constructor/destructor names for<br> ///        later execution.<br> template <typename JITLayerT><br>@@ -246,6 +294,22 @@ class LocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase {<br>   Error enable(JITDylib &JD, MangleAndInterner &Mangler);<br> };<br><br>+/// An interface for Itanium __cxa_atexit interposer implementations.<br>+class ItaniumCXAAtExitSupport {<br>+public:<br>+  struct AtExitRecord {<br>+    void (*F)(void *);<br>+    void *Ctx;<br>+  };<br>+<br>+  void registerAtExit(void (*F)(void *), void *Ctx, void *DSOHandle);<br>+  void runAtExits(void *DSOHandle);<br>+<br>+private:<br>+  std::mutex AtExitsMutex;<br>+  DenseMap<void *, std::vector<AtExitRecord>> AtExitRecords;<br>+};<br>+<br> /// A utility class to expose symbols found via dlsym to the JIT.<br> ///<br> /// If an instance of this class is attached to a JITDylib as a fallback<br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h<br>index bb8270fe80a3..eb74d283f043 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h<br>@@ -31,18 +31,18 @@ class IRCompileLayer : public IRLayer {<br> public:<br>   class IRCompiler {<br>   public:<br>-    IRCompiler(IRMaterializationUnit::ManglingOptions MO) : MO(std::move(MO)) {}<br>+    IRCompiler(IRSymbolMapper::ManglingOptions MO) : MO(std::move(MO)) {}<br>     virtual ~IRCompiler();<br>-    const IRMaterializationUnit::ManglingOptions &getManglingOptions() const {<br>+    const IRSymbolMapper::ManglingOptions &getManglingOptions() const {<br>       return MO;<br>     }<br>     virtual Expected<std::unique_ptr<MemoryBuffer>> operator()(Module &M) = 0;<br><br>   protected:<br>-    IRMaterializationUnit::ManglingOptions &manglingOptions() { return MO; }<br>+    IRSymbolMapper::ManglingOptions &manglingOptions() { return MO; }<br><br>   private:<br>-    IRMaterializationUnit::ManglingOptions MO;<br>+    IRSymbolMapper::ManglingOptions MO;<br>   };<br><br>   using NotifyCompiledFunction =<br>@@ -61,7 +61,7 @@ class IRCompileLayer : public IRLayer {<br>   mutable std::mutex IRLayerMutex;<br>   ObjectLayer &BaseLayer;<br>   std::unique_ptr<IRCompiler> Compile;<br>-  const IRMaterializationUnit::ManglingOptions *ManglingOpts;<br>+  const IRSymbolMapper::ManglingOptions *ManglingOpts;<br>   NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction();<br> };<br><br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h<br>index b71e5b339711..296d74ae6b86 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h<br>@@ -28,7 +28,7 @@ namespace orc {<br> class IRTransformLayer : public IRLayer {<br> public:<br>   using TransformFunction = std::function<Expected<ThreadSafeModule>(<br>-      ThreadSafeModule, const MaterializationResponsibility &R)>;<br>+      ThreadSafeModule, MaterializationResponsibility &R)>;<br><br>   IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer,<br>                    TransformFunction Transform = identityTransform);<br>@@ -39,9 +39,8 @@ class IRTransformLayer : public IRLayer {<br><br>   void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;<br><br>-  static ThreadSafeModule<br>-  identityTransform(ThreadSafeModule TSM,<br>-                    const MaterializationResponsibility &R) {<br>+  static ThreadSafeModule identityTransform(ThreadSafeModule TSM,<br>+                                            MaterializationResponsibility &R) {<br>     return TSM;<br>   }<br><br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h<br>index a9ab3a630a64..880c8ff44c5f 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h<br>@@ -201,7 +201,7 @@ class JITCompileCallbackManager {<br>                             ExecutionSession &ES,<br>                             JITTargetAddress ErrorHandlerAddress)<br>       : TP(std::move(TP)), ES(ES),<br>-        CallbacksJD(ES.createJITDylib("<Callbacks>")),<br>+        CallbacksJD(ES.createBareJITDylib("<Callbacks>")),<br>         ErrorHandlerAddress(ErrorHandlerAddress) {}<br><br>   void setTrampolinePool(std::unique_ptr<TrampolinePool> TP) {<br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h<br>index 3374a29f04df..c0b5012f801f 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h<br>@@ -35,7 +35,23 @@ class LLLazyJITBuilderState;<br> class LLJIT {<br>   template <typename, typename, typename> friend class LLJITBuilderSetters;<br><br>+  friend void setUpGenericLLVMIRPlatform(LLJIT &J);<br>+<br> public:<br>+  /// Initializer support for LLJIT.<br>+  class PlatformSupport {<br>+  public:<br>+    virtual ~PlatformSupport();<br>+<br>+    virtual Error initialize(JITDylib &JD) = 0;<br>+<br>+    virtual Error deinitialize(JITDylib &JD) = 0;<br>+<br>+  protected:<br>+    static void setInitTransform(LLJIT &J,<br>+                                 IRTransformLayer::TransformFunction T);<br>+  };<br>+<br>   static Expected<std::unique_ptr<LLJIT>> Create(LLJITBuilderState &S);<br><br>   /// Destruct this instance. If a multi-threaded instance, waits for all<br>@@ -52,7 +68,7 @@ class LLJIT {<br>   const DataLayout &getDataLayout() const { return DL; }<br><br>   /// Returns a reference to the JITDylib representing the JIT'd main program.<br>-  JITDylib &getMainJITDylib() { return Main; }<br>+  JITDylib &getMainJITDylib() { return *Main; }<br><br>   /// Returns the JITDylib with the given name, or nullptr if no JITDylib with<br>   /// that name exists.<br>@@ -66,7 +82,7 @@ class LLJIT {<br>   /// input or elsewhere in the environment then the client should check<br>   /// (e.g. by calling getJITDylibByName) that the given name is not already in<br>   /// use.<br>-  JITDylib &createJITDylib(std::string Name) {<br>+  Expected<JITDylib &> createJITDylib(std::string Name) {<br>     return ES->createJITDylib(std::move(Name));<br>   }<br><br>@@ -78,7 +94,7 @@ class LLJIT {<br><br>   /// Adds an IR module to the Main JITDylib.<br>   Error addIRModule(ThreadSafeModule TSM) {<br>-    return addIRModule(Main, std::move(TSM));<br>+    return addIRModule(*Main, std::move(TSM));<br>   }<br><br>   /// Adds an object file to the given JITDylib.<br>@@ -86,7 +102,7 @@ class LLJIT {<br><br>   /// Adds an object file to the given JITDylib.<br>   Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {<br>-    return addObjectFile(Main, std::move(Obj));<br>+    return addObjectFile(*Main, std::move(Obj));<br>   }<br><br>   /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to<br>@@ -98,7 +114,7 @@ class LLJIT {<br>   /// (to look up symbols based on their IR name use the lookup function<br>   /// instead).<br>   Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) {<br>-    return lookupLinkerMangled(Main, Name);<br>+    return lookupLinkerMangled(*Main, Name);<br>   }<br><br>   /// Look up a symbol in JITDylib JD based on its IR symbol name.<br>@@ -108,14 +124,28 @@ class LLJIT {<br><br>   /// Look up a symbol in the main JITDylib based on its IR symbol name.<br>   Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) {<br>-    return lookup(Main, UnmangledName);<br>+    return lookup(*Main, UnmangledName);<br>   }<br><br>-  /// Runs all not-yet-run static constructors.<br>-  Error runConstructors() { return CtorRunner.run(); }<br>+  /// Set the PlatformSupport instance.<br>+  void setPlatformSupport(std::unique_ptr<PlatformSupport> PS) {<br>+    this->PS = std::move(PS);<br>+  }<br><br>-  /// Runs all not-yet-run static destructors.<br>-  Error runDestructors() { return DtorRunner.run(); }<br>+  /// Get the PlatformSupport instance.<br>+  PlatformSupport *getPlatformSupport() { return PS.get(); }<br>+<br>+  /// Run the initializers for the given JITDylib.<br>+  Error initialize(JITDylib &JD) {<br>+    assert(PS && "PlatformSupport must be set to run initializers.");<br>+    return PS->initialize(JD);<br>+  }<br>+<br>+  /// Run the deinitializers for the given JITDylib.<br>+  Error deinitialize(JITDylib &JD) {<br>+    assert(PS && "PlatformSupport must be set to run initializers.");<br>+    return PS->deinitialize(JD);<br>+  }<br><br>   /// Returns a reference to the ObjLinkingLayer<br>   ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }<br>@@ -126,6 +156,9 @@ class LLJIT {<br>   /// Returns a reference to the IR transform layer.<br>   IRTransformLayer &getIRTransformLayer() { return *TransformLayer; }<br><br>+  /// Returns a reference to the IR compile layer.<br>+  IRCompileLayer &getIRCompileLayer() { return *CompileLayer; }<br>+<br> protected:<br>   static std::unique_ptr<ObjectLayer><br>   createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);<br>@@ -143,7 +176,9 @@ class LLJIT {<br>   void recordCtorDtors(Module &M);<br><br>   std::unique_ptr<ExecutionSession> ES;<br>-  JITDylib &Main;<br>+  std::unique_ptr<PlatformSupport> PS;<br>+<br>+  JITDylib *Main = nullptr;<br><br>   DataLayout DL;<br>   Triple TT;<br>@@ -153,8 +188,7 @@ class LLJIT {<br>   ObjectTransformLayer ObjTransformLayer;<br>   std::unique_ptr<IRCompileLayer> CompileLayer;<br>   std::unique_ptr<IRTransformLayer> TransformLayer;<br>-<br>-  CtorDtorRunner CtorRunner, DtorRunner;<br>+  std::unique_ptr<IRTransformLayer> InitHelperTransformLayer;<br> };<br><br> /// An extended version of LLJIT that supports lazy function-at-a-time<br>@@ -175,7 +209,7 @@ class LLLazyJIT : public LLJIT {<br><br>   /// Add a module to be lazily compiled to the main JITDylib.<br>   Error addLazyIRModule(ThreadSafeModule M) {<br>-    return addLazyIRModule(Main, std::move(M));<br>+    return addLazyIRModule(*Main, std::move(M));<br>   }<br><br> private:<br>@@ -196,10 +230,14 @@ class LLJITBuilderState {<br>       std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(<br>           JITTargetMachineBuilder JTMB)>;<br><br>+  using PlatformSetupFunction = std::function<Error(LLJIT &J)>;<br>+<br>   std::unique_ptr<ExecutionSession> ES;<br>   Optional<JITTargetMachineBuilder> JTMB;<br>+  Optional<DataLayout> DL;<br>   ObjectLinkingLayerCreator CreateObjectLinkingLayer;<br>   CompileFunctionCreator CreateCompileFunction;<br>+  PlatformSetupFunction SetUpPlatform;<br>   unsigned NumCompileThreads = 0;<br><br>   /// Called prior to JIT class construcion to fix up defaults.<br>@@ -224,6 +262,13 @@ class LLJITBuilderSetters {<br>     return impl().JTMB;<br>   }<br><br>+  /// Set a DataLayout for this instance. If no data layout is specified then<br>+  /// the target's default data layout will be used.<br>+  SetterImpl &setDataLayout(Optional<DataLayout> DL) {<br>+    impl().DL = std::move(DL);<br>+    return impl();<br>+  }<br>+<br>   /// Set an ObjectLinkingLayer creation function.<br>   ///<br>   /// If this method is not called, a default creation function will be used<br>@@ -246,6 +291,16 @@ class LLJITBuilderSetters {<br>     return impl();<br>   }<br><br>+  /// Set up an PlatformSetupFunction.<br>+  ///<br>+  /// If this method is not called then setUpGenericLLVMIRPlatform<br>+  /// will be used to configure the JIT's platform support.<br>+  SetterImpl &<br>+  setPlatformSetUp(LLJITBuilderState::PlatformSetupFunction SetUpPlatform) {<br>+    impl().SetUpPlatform = std::move(SetUpPlatform);<br>+    return impl();<br>+  }<br>+<br>   /// Set the number of compile threads to use.<br>   ///<br>   /// If set to zero, compilation will be performed on the execution thread when<br>@@ -334,6 +389,26 @@ class LLLazyJITBuilder<br>       public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,<br>                                      LLLazyJITBuilderState> {};<br><br>+/// Configure the LLJIT instance to scrape modules for llvm.global_ctors and<br>+/// llvm.global_dtors variables and (if present) build initialization and<br>+/// deinitialization functions. Platform specific initialization configurations<br>+/// should be preferred where available.<br>+void setUpGenericLLVMIRPlatform(LLJIT &J);<br>+<br>+/// Configure the LLJIT instance to use MachOPlatform support.<br>+///<br>+/// Warning: MachOPlatform *requires* that LLJIT be configured to use<br>+/// ObjectLinkingLayer (default on platforms supported by JITLink). If<br>+/// MachOPlatform is used with RTDyldObjectLinkingLayer it will result in<br>+/// undefined behavior).<br>+///<br>+/// MachOPlatform installs an ObjectLinkingLayer plugin to scrape initializers<br>+/// from the __mod_inits section. It also provides interposes for the dlfcn<br>+/// functions (dlopen, dlclose, dlsym, dlerror) that work for JITDylibs as<br>+/// well as regular libraries (JITDylibs will be preferenced, so make sure<br>+/// your JITDylib names do not shadow any real library paths).<br>+Error setUpMachOPlatform(LLJIT &J);<br>+<br> } // End namespace orc<br> } // End namespace llvm<br><br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h<br>index 95e32b2431a0..e843d0f56245 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h<br>@@ -14,6 +14,7 @@<br> #define LLVM_EXECUTIONENGINE_ORC_LAYER_H<br><br> #include "llvm/ExecutionEngine/Orc/Core.h"<br>+#include "llvm/ExecutionEngine/Orc/Mangling.h"<br> #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"<br> #include "llvm/IR/Module.h"<br> #include "llvm/Support/MemoryBuffer.h"<br>@@ -27,15 +28,12 @@ namespace orc {<br> /// their linkage is changed to available-externally.<br> class IRMaterializationUnit : public MaterializationUnit {<br> public:<br>-  struct ManglingOptions {<br>-    bool EmulatedTLS = false;<br>-  };<br>-<br>   using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;<br><br>   /// Create an IRMaterializationLayer. Scans the module to build the<br>   /// SymbolFlags and SymbolToDefinition maps.<br>-  IRMaterializationUnit(ExecutionSession &ES, const ManglingOptions &MO,<br>+  IRMaterializationUnit(ExecutionSession &ES,<br>+                        const IRSymbolMapper::ManglingOptions &MO,<br>                         ThreadSafeModule TSM, VModuleKey K);<br><br>   /// Create an IRMaterializationLayer from a module, and pre-existing<br>@@ -44,12 +42,13 @@ class IRMaterializationUnit : public MaterializationUnit {<br>   /// This constructor is useful for delegating work from one<br>   /// IRMaterializationUnit to another.<br>   IRMaterializationUnit(ThreadSafeModule TSM, VModuleKey K,<br>-                        SymbolFlagsMap SymbolFlags,<br>+                        SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol,<br>                         SymbolNameToDefinitionMap SymbolToDefinition);<br><br>   /// Return the ModuleIdentifier as the name for this MaterializationUnit.<br>   StringRef getName() const override;<br><br>+  /// Return a reference to the contained ThreadSafeModule.<br>   const ThreadSafeModule &getModule() const { return TSM; }<br><br> protected:<br>@@ -57,14 +56,16 @@ class IRMaterializationUnit : public MaterializationUnit {<br>   SymbolNameToDefinitionMap SymbolToDefinition;<br><br> private:<br>+  static SymbolStringPtr getInitSymbol(ExecutionSession &ES,<br>+                                       const ThreadSafeModule &TSM);<br>+<br>   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;<br> };<br><br> /// Interface for layers that accept LLVM IR.<br> class IRLayer {<br> public:<br>-  IRLayer(ExecutionSession &ES,<br>-          const IRMaterializationUnit::ManglingOptions *&MO)<br>+  IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO)<br>       : ES(ES), MO(MO) {}<br><br>   virtual ~IRLayer();<br>@@ -73,7 +74,7 @@ class IRLayer {<br>   ExecutionSession &getExecutionSession() { return ES; }<br><br>   /// Get the mangling options for this layer.<br>-  const IRMaterializationUnit::ManglingOptions *&getManglingOptions() const {<br>+  const IRSymbolMapper::ManglingOptions *&getManglingOptions() const {<br>     return MO;<br>   }<br><br>@@ -104,14 +105,15 @@ class IRLayer {<br> private:<br>   bool CloneToNewContextOnEmit = false;<br>   ExecutionSession &ES;<br>-  const IRMaterializationUnit::ManglingOptions *&MO;<br>+  const IRSymbolMapper::ManglingOptions *&MO;<br> };<br><br> /// MaterializationUnit that materializes modules by calling the 'emit' method<br> /// on the given IRLayer.<br> class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {<br> public:<br>-  BasicIRLayerMaterializationUnit(IRLayer &L, const ManglingOptions &MO,<br>+  BasicIRLayerMaterializationUnit(IRLayer &L,<br>+                                  const IRSymbolMapper::ManglingOptions &MO,<br>                                   ThreadSafeModule TSM, VModuleKey K);<br><br> private:<br>@@ -153,7 +155,8 @@ class BasicObjectLayerMaterializationUnit : public MaterializationUnit {<br><br>   BasicObjectLayerMaterializationUnit(ObjectLayer &L, VModuleKey K,<br>                                       std::unique_ptr<MemoryBuffer> O,<br>-                                      SymbolFlagsMap SymbolFlags);<br>+                                      SymbolFlagsMap SymbolFlags,<br>+                                      SymbolStringPtr InitSymbol);<br><br>   /// Return the buffer's identifier as the name for this MaterializationUnit.<br>   StringRef getName() const override;<br>@@ -167,12 +170,6 @@ class BasicObjectLayerMaterializationUnit : public MaterializationUnit {<br>   std::unique_ptr<MemoryBuffer> O;<br> };<br><br>-/// Returns a SymbolFlagsMap for the object file represented by the given<br>-/// buffer, or an error if the buffer does not contain a valid object file.<br>-// FIXME: Maybe move to Core.h?<br>-Expected<SymbolFlagsMap> getObjectSymbolFlags(ExecutionSession &ES,<br>-                                              MemoryBufferRef ObjBuffer);<br>-<br> } // End namespace orc<br> } // End namespace llvm<br><br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h<br>new file mode 100644<br>index 000000000000..92c1a04921b8<br>--- /dev/null<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h<br>@@ -0,0 +1,147 @@<br>+//===-- MachOPlatform.h - Utilities for executing MachO in Orc --*- C++ -*-===//<br>+//<br>+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>+// See <a href="https://llvm.org/LICENSE.txt" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>+//<br>+//===----------------------------------------------------------------------===//<br>+//<br>+// Utilities for executing JIT'd MachO in Orc.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#ifndef LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H<br>+#define LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H<br>+<br>+#include "llvm/ADT/StringRef.h"<br>+#include "llvm/ExecutionEngine/Orc/Core.h"<br>+#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"<br>+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"<br>+<br>+#include <future><br>+#include <thread><br>+#include <vector><br>+<br>+namespace llvm {<br>+namespace orc {<br>+<br>+/// Enable registration of JIT'd ObjC classes and selectors.<br>+Error enableObjCRegistration(const char *PathToLibObjC);<br>+bool objCRegistrationEnabled();<br>+<br>+class MachOJITDylibInitializers {<br>+public:<br>+  struct SectionExtent {<br>+    SectionExtent() = default;<br>+    SectionExtent(JITTargetAddress Address, uint64_t NumPtrs)<br>+        : Address(Address), NumPtrs(NumPtrs) {}<br>+    JITTargetAddress Address = 0;<br>+    uint64_t NumPtrs = 0;<br>+  };<br>+<br>+  void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {<br>+    this->ObjCImageInfoAddr = ObjCImageInfoAddr;<br>+  }<br>+<br>+  void addModInitsSection(SectionExtent ModInit) {<br>+    ModInitSections.push_back(std::move(ModInit));<br>+  }<br>+<br>+  void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {<br>+    ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));<br>+  }<br>+<br>+  void addObjCClassListSection(SectionExtent ObjCClassList) {<br>+    ObjCClassListSections.push_back(std::move(ObjCClassList));<br>+  }<br>+<br>+  void runModInits() const;<br>+  void registerObjCSelectors() const;<br>+  Error registerObjCClasses() const;<br>+<br>+  void dump() const;<br>+<br>+private:<br>+  using RawPointerSectionList = std::vector<SectionExtent>;<br>+<br>+  JITTargetAddress ObjCImageInfoAddr;<br>+  RawPointerSectionList ModInitSections;<br>+  RawPointerSectionList ObjCSelRefsSections;<br>+  RawPointerSectionList ObjCClassListSections;<br>+};<br>+<br>+class MachOJITDylibDeinitializers {};<br>+<br>+/// Mediates between MachO initialization and ExecutionSession state.<br>+class MachOPlatform : public Platform {<br>+public:<br>+  using InitializerSequence =<br>+      std::vector<std::pair<JITDylib *, MachOJITDylibInitializers>>;<br>+<br>+  using DeinitializerSequence =<br>+      std::vector<std::pair<JITDylib *, MachOJITDylibDeinitializers>>;<br>+<br>+  MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,<br>+                std::unique_ptr<MemoryBuffer> StandardSymbolsObject);<br>+<br>+  ExecutionSession &getExecutionSession() const { return ES; }<br>+<br>+  Error setupJITDylib(JITDylib &JD) override;<br>+  Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) override;<br>+  Error notifyRemoving(JITDylib &JD, VModuleKey K) override;<br>+<br>+  Expected<InitializerSequence> getInitializerSequence(JITDylib &JD);<br>+<br>+  Expected<DeinitializerSequence> getDeinitializerSequence(JITDylib &JD);<br>+<br>+private:<br>+  // This ObjectLinkingLayer plugin scans JITLink graphs for __mod_init_func,<br>+  // __objc_classlist and __sel_ref sections and records their extents so that<br>+  // they can be run in the target process.<br>+  class InitScraperPlugin : public ObjectLinkingLayer::Plugin {<br>+  public:<br>+    InitScraperPlugin(MachOPlatform &MP) : MP(MP) {}<br>+<br>+    void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,<br>+                          jitlink::PassConfiguration &Config) override;<br>+<br>+    LocalDependenciesMap getSyntheticSymbolLocalDependencies(<br>+        MaterializationResponsibility &MR) override;<br>+<br>+  private:<br>+    using InitSymbolDepMap =<br>+        DenseMap<MaterializationResponsibility *, JITLinkSymbolVector>;<br>+<br>+    void preserveInitSectionIfPresent(JITLinkSymbolVector &Syms,<br>+                                      jitlink::LinkGraph &G,<br>+                                      StringRef SectionName);<br>+<br>+    Error processObjCImageInfo(jitlink::LinkGraph &G,<br>+                               MaterializationResponsibility &MR);<br>+<br>+    std::mutex InitScraperMutex;<br>+    MachOPlatform &MP;<br>+    DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;<br>+    InitSymbolDepMap InitSymbolDeps;<br>+  };<br>+<br>+  static std::vector<JITDylib *> getDFSLinkOrder(JITDylib &JD);<br>+<br>+  void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,<br>+                        MachOJITDylibInitializers::SectionExtent ModInits,<br>+                        MachOJITDylibInitializers::SectionExtent ObjCSelRefs,<br>+                        MachOJITDylibInitializers::SectionExtent ObjCClassList);<br>+<br>+  std::mutex PlatformMutex;<br>+  ExecutionSession &ES;<br>+  ObjectLinkingLayer &ObjLinkingLayer;<br>+  std::unique_ptr<MemoryBuffer> StandardSymbolsObject;<br>+<br>+  DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;<br>+  DenseMap<JITDylib *, MachOJITDylibInitializers> InitSeqs;<br>+};<br>+<br>+} // end namespace orc<br>+} // end namespace llvm<br>+<br>+#endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H<br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h b/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h<br>new file mode 100644<br>index 000000000000..e0f770a601fb<br>--- /dev/null<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h<br>@@ -0,0 +1,66 @@<br>+//===------ Mangling.h -- Name Mangling Utilities for ORC -------*- C++ -*-===//<br>+//<br>+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>+// See <a href="https://llvm.org/LICENSE.txt" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>+//<br>+//===----------------------------------------------------------------------===//<br>+//<br>+// Name mangling utilities for ORC.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#ifndef LLVM_EXECUTIONENGINE_ORC_MANGLING_H<br>+#define LLVM_EXECUTIONENGINE_ORC_MANGLING_H<br>+<br>+#include "llvm/ExecutionEngine/Orc/Core.h"<br>+#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"<br>+#include "llvm/IR/Module.h"<br>+#include "llvm/Support/MemoryBuffer.h"<br>+<br>+namespace llvm {<br>+namespace orc {<br>+<br>+/// Mangles symbol names then uniques them in the context of an<br>+/// ExecutionSession.<br>+class MangleAndInterner {<br>+public:<br>+  MangleAndInterner(ExecutionSession &ES, const DataLayout &DL);<br>+  SymbolStringPtr operator()(StringRef Name);<br>+<br>+private:<br>+  ExecutionSession &ES;<br>+  const DataLayout &DL;<br>+};<br>+<br>+/// Maps IR global values to their linker symbol names / flags.<br>+///<br>+/// This utility can be used when adding new IR globals in the JIT.<br>+class IRSymbolMapper {<br>+public:<br>+  struct ManglingOptions {<br>+    bool EmulatedTLS = false;<br>+  };<br>+<br>+  using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;<br>+<br>+  /// Add mangled symbols for the given GlobalValues to SymbolFlags.<br>+  /// If a SymbolToDefinitionMap pointer is supplied then it will be populated<br>+  /// with Name-to-GlobalValue* mappings. Note that this mapping is not<br>+  /// necessarily one-to-one: thread-local GlobalValues, for example, may<br>+  /// produce more than one symbol, in which case the map will contain duplicate<br>+  /// values.<br>+  static void add(ExecutionSession &ES, const ManglingOptions &MO,<br>+                  ArrayRef<GlobalValue *> GVs, SymbolFlagsMap &SymbolFlags,<br>+                  SymbolNameToDefinitionMap *SymbolToDefinition = nullptr);<br>+};<br>+<br>+/// Returns a SymbolFlagsMap for the object file represented by the given<br>+/// buffer, or an error if the buffer does not contain a valid object file.<br>+Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>><br>+getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer);<br>+<br>+} // End namespace orc<br>+} // End namespace llvm<br>+<br>+#endif // LLVM_EXECUTIONENGINE_ORC_MANGLING_H<br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h<br>index 50d25f18891e..1b4c03bd2cfd 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h<br>@@ -35,6 +35,7 @@ namespace llvm {<br><br> namespace jitlink {<br> class EHFrameRegistrar;<br>+class Symbol;<br> } // namespace jitlink<br><br> namespace object {<br>@@ -59,10 +60,14 @@ class ObjectLinkingLayer : public ObjectLayer {<br>   /// configured.<br>   class Plugin {<br>   public:<br>+    using JITLinkSymbolVector = std::vector<const jitlink::Symbol *>;<br>+    using LocalDependenciesMap = DenseMap<SymbolStringPtr, JITLinkSymbolVector>;<br>+<br>     virtual ~Plugin();<br>     virtual void modifyPassConfig(MaterializationResponsibility &MR,<br>                                   const Triple &TT,<br>                                   jitlink::PassConfiguration &Config) {}<br>+<br>     virtual void notifyLoaded(MaterializationResponsibility &MR) {}<br>     virtual Error notifyEmitted(MaterializationResponsibility &MR) {<br>       return Error::success();<br>@@ -71,6 +76,15 @@ class ObjectLinkingLayer : public ObjectLayer {<br>       return Error::success();<br>     }<br>     virtual Error notifyRemovingAllModules() { return Error::success(); }<br>+<br>+    /// Return any dependencies that synthetic symbols (e.g. init symbols)<br>+    /// have on locally scoped jitlink::Symbols. This is used by the<br>+    /// ObjectLinkingLayer to update the dependencies for the synthetic<br>+    /// symbols.<br>+    virtual LocalDependenciesMap<br>+    getSyntheticSymbolLocalDependencies(MaterializationResponsibility &MR) {<br>+      return LocalDependenciesMap();<br>+    }<br>   };<br><br>   using ReturnObjectBufferFunction =<br><br>diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h<br>index c354f6c3559c..c8462dc3d2c8 100644<br>--- a/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h<br>+++ b/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h<br>@@ -53,6 +53,7 @@ class SymbolStringPtr {<br><br> public:<br>   SymbolStringPtr() = default;<br>+  SymbolStringPtr(nullptr_t) {}<br>   SymbolStringPtr(const SymbolStringPtr &Other)<br>     : S(Other.S) {<br>     if (isRealPoolEntry(S))<br>@@ -85,6 +86,8 @@ class SymbolStringPtr {<br>       --S->getValue();<br>   }<br><br>+  explicit operator bool() const { return S; }<br>+<br>   StringRef operator*() const { return S->first(); }<br><br>   friend bool operator==(const SymbolStringPtr &LHS,<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt<br>index e3a7a67c8a0e..7eb2742d7b53 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt<br>+++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt<br>@@ -12,6 +12,8 @@ add_llvm_component_library(LLVMOrcJIT<br>   Legacy.cpp<br>   Layer.cpp<br>   LLJIT.cpp<br>+  MachOPlatform.cpp<br>+  Mangling.cpp<br>   NullResolver.cpp<br>   ObjectLinkingLayer.cpp<br>   ObjectTransformLayer.cpp<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp<br>index 29d18b6e4d7b..f22ae01a2080 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp<br>@@ -7,6 +7,7 @@<br> //===----------------------------------------------------------------------===//<br><br> #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"<br>+#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"<br> #include "llvm/IR/Mangler.h"<br> #include "llvm/IR/Module.h"<br><br>@@ -68,18 +69,18 @@ namespace orc {<br> class PartitioningIRMaterializationUnit : public IRMaterializationUnit {<br> public:<br>   PartitioningIRMaterializationUnit(ExecutionSession &ES,<br>-                                    const ManglingOptions &MO,<br>+                                    const IRSymbolMapper::ManglingOptions &MO,<br>                                     ThreadSafeModule TSM, VModuleKey K,<br>                                     CompileOnDemandLayer &Parent)<br>       : IRMaterializationUnit(ES, MO, std::move(TSM), std::move(K)),<br>         Parent(Parent) {}<br><br>   PartitioningIRMaterializationUnit(<br>-      ThreadSafeModule TSM, SymbolFlagsMap SymbolFlags,<br>-      SymbolNameToDefinitionMap SymbolToDefinition,<br>+      ThreadSafeModule TSM, VModuleKey K, SymbolFlagsMap SymbolFlags,<br>+      SymbolStringPtr InitSymbol, SymbolNameToDefinitionMap SymbolToDefinition,<br>       CompileOnDemandLayer &Parent)<br>       : IRMaterializationUnit(std::move(TSM), std::move(K),<br>-                              std::move(SymbolFlags),<br>+                              std::move(SymbolFlags), std::move(InitSymbol),<br>                               std::move(SymbolToDefinition)),<br>         Parent(Parent) {}<br><br>@@ -172,21 +173,23 @@ CompileOnDemandLayer::getPerDylibResources(JITDylib &TargetD) {<br>   auto I = DylibResources.find(&TargetD);<br>   if (I == DylibResources.end()) {<br>     auto &ImplD =<br>-        getExecutionSession().createJITDylib(TargetD.getName() + ".impl");<br>+        getExecutionSession().createBareJITDylib(TargetD.getName() + ".impl");<br>+    JITDylibSearchOrder NewSearchOrder;<br>     TargetD.withSearchOrderDo(<br>         [&](const JITDylibSearchOrder &TargetSearchOrder) {<br>-          auto NewSearchOrder = TargetSearchOrder;<br>-          assert(<br>-              !NewSearchOrder.empty() &&<br>-              NewSearchOrder.front().first == &TargetD &&<br>-              NewSearchOrder.front().second ==<br>-                  JITDylibLookupFlags::MatchAllSymbols &&<br>-              "TargetD must be at the front of its own search order and match "<br>-              "non-exported symbol");<br>-          NewSearchOrder.insert(std::next(NewSearchOrder.begin()),<br>-                                {&ImplD, JITDylibLookupFlags::MatchAllSymbols});<br>-          ImplD.setSearchOrder(std::move(NewSearchOrder), false);<br>+          NewSearchOrder = TargetSearchOrder;<br>         });<br>+<br>+    assert(<br>+        !NewSearchOrder.empty() && NewSearchOrder.front().first == &TargetD &&<br>+        NewSearchOrder.front().second == JITDylibLookupFlags::MatchAllSymbols &&<br>+        "TargetD must be at the front of its own search order and match "<br>+        "non-exported symbol");<br>+    NewSearchOrder.insert(std::next(NewSearchOrder.begin()),<br>+                          {&ImplD, JITDylibLookupFlags::MatchAllSymbols});<br>+    ImplD.setSearchOrder(NewSearchOrder, false);<br>+    TargetD.setSearchOrder(std::move(NewSearchOrder), false);<br>+<br>     PerDylibResources PDR(ImplD, BuildIndirectStubsManager());<br>     I = DylibResources.insert(std::make_pair(&TargetD, std::move(PDR))).first;<br>   }<br>@@ -251,8 +254,15 @@ void CompileOnDemandLayer::emitPartition(<br>   auto &ES = getExecutionSession();<br>   GlobalValueSet RequestedGVs;<br>   for (auto &Name : R.getRequestedSymbols()) {<br>-    assert(Defs.count(Name) && "No definition for symbol");<br>-    RequestedGVs.insert(Defs[Name]);<br>+    if (Name == R.getInitializerSymbol())<br>+      TSM.withModuleDo([&](Module &M) {<br>+        for (auto &GV : getStaticInitGVs(M))<br>+          RequestedGVs.insert(&GV);<br>+      });<br>+    else {<br>+      assert(Defs.count(Name) && "No definition for symbol");<br>+      RequestedGVs.insert(Defs[Name]);<br>+    }<br>   }<br><br>   /// Perform partitioning with the context lock held, since the partition<br>@@ -272,7 +282,8 @@ void CompileOnDemandLayer::emitPartition(<br>   // If the partition is empty, return the whole module to the symbol table.<br>   if (GVsToExtract->empty()) {<br>     R.replace(std::make_unique<PartitioningIRMaterializationUnit>(<br>-        std::move(TSM), R.getSymbols(), std::move(Defs), *this));<br>+        std::move(TSM), R.getVModuleKey(), R.getSymbols(),<br>+        R.getInitializerSymbol(), std::move(Defs), *this));<br>     return;<br>   }<br><br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp<br>index 160e5ba50311..f8efed15edea 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp<br>@@ -24,9 +24,9 @@<br> namespace llvm {<br> namespace orc {<br><br>-IRMaterializationUnit::ManglingOptions<br>+IRSymbolMapper::ManglingOptions<br> irManglingOptionsFromTargetOptions(const TargetOptions &Opts) {<br>-  IRMaterializationUnit::ManglingOptions MO;<br>+  IRSymbolMapper::ManglingOptions MO;<br><br>   MO.EmulatedTLS = Opts.EmulatedTLS;<br><br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp<br>index a7af34a21926..6a0df10f7c3f 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/Core.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp<br>@@ -11,7 +11,6 @@<br> #include "llvm/ADT/STLExtras.h"<br> #include "llvm/Config/llvm-config.h"<br> #include "llvm/ExecutionEngine/Orc/OrcError.h"<br>-#include "llvm/IR/Mangler.h"<br> #include "llvm/Support/CommandLine.h"<br> #include "llvm/Support/Debug.h"<br> #include "llvm/Support/Format.h"<br>@@ -421,12 +420,6 @@ void AsynchronousSymbolQuery::detach() {<br>   QueryRegistrations.clear();<br> }<br><br>-MaterializationResponsibility::MaterializationResponsibility(<br>-    JITDylib &JD, SymbolFlagsMap SymbolFlags, VModuleKey K)<br>-    : JD(JD), SymbolFlags(std::move(SymbolFlags)), K(std::move(K)) {<br>-  assert(!this->SymbolFlags.empty() && "Materializing nothing?");<br>-}<br>-<br> MaterializationResponsibility::~MaterializationResponsibility() {<br>   assert(SymbolFlags.empty() &&<br>          "All symbols should have been explicitly materialized or failed");<br>@@ -501,9 +494,13 @@ void MaterializationResponsibility::failMaterialization() {<br><br> void MaterializationResponsibility::replace(<br>     std::unique_ptr<MaterializationUnit> MU) {<br>+<br>   for (auto &KV : MU->getSymbols())<br>     SymbolFlags.erase(KV.first);<br><br>+  if (MU->getInitializerSymbol() == InitSymbol)<br>+    InitSymbol = nullptr;<br>+<br>   LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() {<br>     dbgs() << "In " << JD.getName() << " replacing symbols with " << *MU<br>            << "\n";<br>@@ -519,6 +516,7 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,<br>   if (NewKey == VModuleKey())<br>     NewKey = K;<br><br>+  SymbolStringPtr DelegatedInitSymbol;<br>   SymbolFlagsMap DelegatedFlags;<br><br>   for (auto &Name : Symbols) {<br>@@ -528,10 +526,14 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols,<br>            "instance");<br><br>     DelegatedFlags[Name] = std::move(I->second);<br>+    if (Name == InitSymbol)<br>+      std::swap(InitSymbol, DelegatedInitSymbol);<br>+<br>     SymbolFlags.erase(I);<br>   }<br><br>   return MaterializationResponsibility(JD, std::move(DelegatedFlags),<br>+                                       std::move(DelegatedInitSymbol),<br>                                        std::move(NewKey));<br> }<br><br>@@ -550,7 +552,7 @@ void MaterializationResponsibility::addDependenciesForAll(<br><br> AbsoluteSymbolsMaterializationUnit::AbsoluteSymbolsMaterializationUnit(<br>     SymbolMap Symbols, VModuleKey K)<br>-    : MaterializationUnit(extractFlags(Symbols), std::move(K)),<br>+    : MaterializationUnit(extractFlags(Symbols), nullptr, std::move(K)),<br>       Symbols(std::move(Symbols)) {}<br><br> StringRef AbsoluteSymbolsMaterializationUnit::getName() const {<br>@@ -581,7 +583,7 @@ AbsoluteSymbolsMaterializationUnit::extractFlags(const SymbolMap &Symbols) {<br> ReExportsMaterializationUnit::ReExportsMaterializationUnit(<br>     JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags,<br>     SymbolAliasMap Aliases, VModuleKey K)<br>-    : MaterializationUnit(extractFlags(Aliases), std::move(K)),<br>+    : MaterializationUnit(extractFlags(Aliases), nullptr, std::move(K)),<br>       SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),<br>       Aliases(std::move(Aliases)) {}<br><br>@@ -972,7 +974,7 @@ void JITDylib::addDependencies(const SymbolStringPtr &Name,<br>       // Assert that this symbol exists and has not reached the ready state<br>       // already.<br>       assert(OtherSymI != OtherJITDylib.Symbols.end() &&<br>-             (OtherSymI->second.getState() != SymbolState::Ready &&<br>+             (OtherSymI->second.getState() < SymbolState::Ready &&<br>               "Dependency on emitted/ready symbol"));<br> #endif<br><br>@@ -1101,6 +1103,7 @@ Error JITDylib::resolve(const SymbolMap &Resolved) {<br> Error JITDylib::emit(const SymbolFlagsMap &Emitted) {<br>   AsynchronousSymbolQuerySet CompletedQueries;<br>   SymbolNameSet SymbolsInErrorState;<br>+  DenseMap<JITDylib *, SymbolNameVector> ReadySymbols;<br><br>   ES.runSessionLocked([&, this]() {<br>     std::vector<SymbolTable::iterator> Worklist;<br>@@ -1145,6 +1148,7 @@ Error JITDylib::emit(const SymbolFlagsMap &Emitted) {<br>       // dependencies) then notify any pending queries.<br>       for (auto &KV : MI.Dependants) {<br>         auto &DependantJD = *KV.first;<br>+        auto &DependantJDReadySymbols = ReadySymbols[&DependantJD];<br>         for (auto &DependantName : KV.second) {<br>           auto DependantMII =<br>               DependantJD.MaterializingInfos.find(DependantName);<br>@@ -1184,6 +1188,7 @@ Error JITDylib::emit(const SymbolFlagsMap &Emitted) {<br>             // Since this dependant is now ready, we erase its MaterializingInfo<br>             // and update its materializing state.<br>             DependantSymEntry.setState(SymbolState::Ready);<br>+            DependantJDReadySymbols.push_back(DependantName);<br><br>             for (auto &Q : DependantMI.takeQueriesMeeting(SymbolState::Ready)) {<br>               Q->notifySymbolMetRequiredState(<br>@@ -1192,22 +1197,21 @@ Error JITDylib::emit(const SymbolFlagsMap &Emitted) {<br>                 CompletedQueries.insert(Q);<br>               Q->removeQueryDependence(DependantJD, DependantName);<br>             }<br>-<br>-            DependantJD.MaterializingInfos.erase(DependantMII);<br>           }<br>         }<br>       }<br><br>+      auto &ThisJDReadySymbols = ReadySymbols[this];<br>       MI.Dependants.clear();<br>       if (MI.UnemittedDependencies.empty()) {<br>         SymI->second.setState(SymbolState::Ready);<br>+        ThisJDReadySymbols.push_back(Name);<br>         for (auto &Q : MI.takeQueriesMeeting(SymbolState::Ready)) {<br>           Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());<br>           if (Q->isComplete())<br>             CompletedQueries.insert(Q);<br>           Q->removeQueryDependence(*this, Name);<br>         }<br>-        MaterializingInfos.erase(MII);<br>       }<br>     }<br>   });<br>@@ -1882,6 +1886,57 @@ void JITDylib::transferEmittedNodeDependencies(<br>   }<br> }<br><br>+Platform::~Platform() {}<br>+<br>+Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(<br>+    ExecutionSession &ES,<br>+    const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms) {<br>+<br>+  DenseMap<JITDylib *, SymbolMap> CompoundResult;<br>+  Error CompoundErr = Error::success();<br>+  std::mutex LookupMutex;<br>+  std::condition_variable CV;<br>+  uint64_t Count = InitSyms.size();<br>+<br>+  LLVM_DEBUG({<br>+    dbgs() << "Issuing init-symbol lookup:\n";<br>+    for (auto &KV : InitSyms)<br>+      dbgs() << "  " << KV.first->getName() << ": " << KV.second << "\n";<br>+  });<br>+<br>+  for (auto &KV : InitSyms) {<br>+    auto *JD = KV.first;<br>+    auto Names = std::move(KV.second);<br>+    ES.lookup(<br>+        LookupKind::Static,<br>+        JITDylibSearchOrder({{JD, JITDylibLookupFlags::MatchAllSymbols}}),<br>+        std::move(Names), SymbolState::Ready,<br>+        [&, JD](Expected<SymbolMap> Result) {<br>+          {<br>+            std::lock_guard<std::mutex> Lock(LookupMutex);<br>+            --Count;<br>+            if (Result) {<br>+              assert(!CompoundResult.count(JD) &&<br>+                     "Duplicate JITDylib in lookup?");<br>+              CompoundResult[JD] = std::move(*Result);<br>+            } else<br>+              CompoundErr =<br>+                  joinErrors(std::move(CompoundErr), Result.takeError());<br>+          }<br>+          CV.notify_one();<br>+        },<br>+        NoDependenciesToRegister);<br>+  }<br>+<br>+  std::unique_lock<std::mutex> Lock(LookupMutex);<br>+  CV.wait(Lock, [&] { return Count == 0 || CompoundErr; });<br>+<br>+  if (CompoundErr)<br>+    return std::move(CompoundErr);<br>+<br>+  return std::move(CompoundResult);<br>+}<br>+<br> ExecutionSession::ExecutionSession(std::shared_ptr<SymbolStringPool> SSP)<br>     : SSP(SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>()) {<br> }<br>@@ -1895,7 +1950,7 @@ JITDylib *ExecutionSession::getJITDylibByName(StringRef Name) {<br>   });<br> }<br><br>-JITDylib &ExecutionSession::createJITDylib(std::string Name) {<br>+JITDylib &ExecutionSession::createBareJITDylib(std::string Name) {<br>   assert(!getJITDylibByName(Name) && "JITDylib with that name already exists");<br>   return runSessionLocked([&, this]() -> JITDylib & {<br>     JDs.push_back(<br>@@ -1904,6 +1959,14 @@ JITDylib &ExecutionSession::createJITDylib(std::string Name) {<br>   });<br> }<br><br>+Expected<JITDylib &> ExecutionSession::createJITDylib(std::string Name) {<br>+  auto &JD = createBareJITDylib(Name);<br>+  if (P)<br>+    if (auto Err = P->setupJITDylib(JD))<br>+      return std::move(Err);<br>+  return JD;<br>+}<br>+<br> void ExecutionSession::legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err) {<br>   assert(!!Err && "Error should be in failure state");<br><br>@@ -2144,11 +2207,11 @@ ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,<br><br> Expected<JITEvaluatedSymbol><br> ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,<br>-                         SymbolStringPtr Name) {<br>+                         SymbolStringPtr Name, SymbolState RequiredState) {<br>   SymbolLookupSet Names({Name});<br><br>   if (auto ResultMap = lookup(SearchOrder, std::move(Names), LookupKind::Static,<br>-                              SymbolState::Ready, NoDependenciesToRegister)) {<br>+                              RequiredState, NoDependenciesToRegister)) {<br>     assert(ResultMap->size() == 1 && "Unexpected number of results");<br>     assert(ResultMap->count(Name) && "Missing result for symbol");<br>     return std::move(ResultMap->begin()->second);<br>@@ -2157,14 +2220,15 @@ ExecutionSession::lookup(const JITDylibSearchOrder &SearchOrder,<br> }<br><br> Expected<JITEvaluatedSymbol><br>-ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder,<br>-                         SymbolStringPtr Name) {<br>-  return lookup(makeJITDylibSearchOrder(SearchOrder), Name);<br>+ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Name,<br>+                         SymbolState RequiredState) {<br>+  return lookup(makeJITDylibSearchOrder(SearchOrder), Name, RequiredState);<br> }<br><br> Expected<JITEvaluatedSymbol><br>-ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name) {<br>-  return lookup(SearchOrder, intern(Name));<br>+ExecutionSession::lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Name,<br>+                         SymbolState RequiredState) {<br>+  return lookup(SearchOrder, intern(Name), RequiredState);<br> }<br><br> void ExecutionSession::dump(raw_ostream &OS) {<br>@@ -2195,17 +2259,5 @@ void ExecutionSession::runOutstandingMUs() {<br>   }<br> }<br><br>-MangleAndInterner::MangleAndInterner(ExecutionSession &ES, const DataLayout &DL)<br>-    : ES(ES), DL(DL) {}<br>-<br>-SymbolStringPtr MangleAndInterner::operator()(StringRef Name) {<br>-  std::string MangledName;<br>-  {<br>-    raw_string_ostream MangledNameStream(MangledName);<br>-    Mangler::getNameWithPrefix(MangledNameStream, Name, DL);<br>-  }<br>-  return ES.intern(MangledName);<br>-}<br>-<br> } // End namespace orc.<br> } // End namespace llvm.<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp<br>index 3d97fe9eeab1..a98445a2295e 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp<br>@@ -113,6 +113,26 @@ iterator_range<CtorDtorIterator> getDestructors(const Module &M) {<br>                     CtorDtorIterator(DtorsList, true));<br> }<br><br>+bool StaticInitGVIterator::isStaticInitGlobal(GlobalValue &GV) {<br>+  if (GV.isDeclaration())<br>+    return false;<br>+<br>+  if (GV.hasName() && (GV.getName() == "llvm.global_ctors" ||<br>+                       GV.getName() == "llvm.global_dtors"))<br>+    return true;<br>+<br>+  if (ObjFmt == Triple::MachO) {<br>+    // FIXME: These section checks are too strict: We should match first and<br>+    // second word split by comma.<br>+    if (GV.hasSection() &&<br>+        (GV.getSection().startswith("__DATA,__objc_classlist") ||<br>+         GV.getSection().startswith("__DATA,__objc_selrefs")))<br>+      return true;<br>+  }<br>+<br>+  return false;<br>+}<br>+<br> void CtorDtorRunner::add(iterator_range<CtorDtorIterator> CtorDtors) {<br>   if (CtorDtors.empty())<br>     return;<br>@@ -198,6 +218,30 @@ Error LocalCXXRuntimeOverrides::enable(JITDylib &JD,<br>   return JD.define(absoluteSymbols(std::move(RuntimeInterposes)));<br> }<br><br>+void ItaniumCXAAtExitSupport::registerAtExit(void (*F)(void *), void *Ctx,<br>+                                             void *DSOHandle) {<br>+  std::lock_guard<std::mutex> Lock(AtExitsMutex);<br>+  AtExitRecords[DSOHandle].push_back({F, Ctx});<br>+}<br>+<br>+void ItaniumCXAAtExitSupport::runAtExits(void *DSOHandle) {<br>+  std::vector<AtExitRecord> AtExitsToRun;<br>+<br>+  {<br>+    std::lock_guard<std::mutex> Lock(AtExitsMutex);<br>+    auto I = AtExitRecords.find(DSOHandle);<br>+    if (I != AtExitRecords.end()) {<br>+      AtExitsToRun = std::move(I->second);<br>+      AtExitRecords.erase(I);<br>+    }<br>+  }<br>+<br>+  while (!AtExitsToRun.empty()) {<br>+    AtExitsToRun.back().F(AtExitsToRun.back().Ctx);<br>+    AtExitsToRun.pop_back();<br>+  }<br>+}<br>+<br> DynamicLibrarySearchGenerator::DynamicLibrarySearchGenerator(<br>     sys::DynamicLibrary Dylib, char GlobalPrefix, SymbolPredicate Allow)<br>     : Dylib(std::move(Dylib)), Allow(std::move(Allow)),<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp<br>index 1ac9a58aeaef..1e991d8f58f2 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp<br>@@ -28,7 +28,7 @@ class CompileCallbackMaterializationUnit : public orc::MaterializationUnit {<br>   CompileCallbackMaterializationUnit(SymbolStringPtr Name,<br>                                      CompileFunction Compile, VModuleKey K)<br>       : MaterializationUnit(SymbolFlagsMap({{Name, JITSymbolFlags::Exported}}),<br>-                            std::move(K)),<br>+                            nullptr, std::move(K)),<br>         Name(std::move(Name)), Compile(std::move(Compile)) {}<br><br>   StringRef getName() const override { return "<Compile Callbacks>"; }<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp<br>index 4218ca4e481f..5b2f86823355 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp<br>@@ -8,15 +8,827 @@<br><br> #include "llvm/ExecutionEngine/Orc/LLJIT.h"<br> #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"<br>+#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"<br> #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"<br> #include "llvm/ExecutionEngine/Orc/OrcError.h"<br> #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"<br> #include "llvm/ExecutionEngine/SectionMemoryManager.h"<br>+#include "llvm/IR/GlobalVariable.h"<br>+#include "llvm/IR/IRBuilder.h"<br> #include "llvm/IR/Mangler.h"<br>+#include "llvm/IR/Module.h"<br>+#include "llvm/Support/DynamicLibrary.h"<br>+<br>+#include <map><br>+<br>+using namespace llvm;<br>+using namespace llvm::orc;<br>+<br>+namespace {<br>+<br>+/// Add a reference to the __dso_handle global to the given module.<br>+/// Returns a reference to the __dso_handle IR decl.<br>+GlobalVariable *addDSOHandleDecl(Module &M) {<br>+  auto DSOHandleTy = StructType::create(M.getContext(), "lljit.dso_handle");<br>+  return new GlobalVariable(M, DSOHandleTy, true, GlobalValue::ExternalLinkage,<br>+                            nullptr, "__dso_handle");<br>+}<br>+<br>+/// Adds helper function decls and wrapper functions that call the helper with<br>+/// some additional prefix arguments.<br>+///<br>+/// E.g. For wrapper "foo" with type i8(i8, i64), helper "bar", and prefix<br>+/// args i32 4 and i16 12345, this function will add:<br>+///<br>+/// declare i8 @bar(i32, i16, i8, i64)<br>+///<br>+/// define i8 @foo(i8, i64) {<br>+/// entry:<br>+///   %2 = call i8 @bar(i32 4, i16 12345, i8 %0, i64 %1)<br>+///   ret i8 %2<br>+/// }<br>+///<br>+Function *addHelperAndWrapper(Module &M, StringRef WrapperName,<br>+                              FunctionType *WrapperFnType,<br>+                              GlobalValue::VisibilityTypes WrapperVisibility,<br>+                              StringRef HelperName,<br>+                              ArrayRef<Value *> HelperPrefixArgs) {<br>+  std::vector<Type *> HelperArgTypes;<br>+  for (auto *Arg : HelperPrefixArgs)<br>+    HelperArgTypes.push_back(Arg->getType());<br>+  for (auto *T : WrapperFnType->params())<br>+    HelperArgTypes.push_back(T);<br>+  auto *HelperFnType =<br>+      FunctionType::get(WrapperFnType->getReturnType(), HelperArgTypes, false);<br>+  auto *HelperFn = Function::Create(HelperFnType, GlobalValue::ExternalLinkage,<br>+                                    HelperName, M);<br>+<br>+  auto *WrapperFn = Function::Create(<br>+      WrapperFnType, GlobalValue::ExternalLinkage, WrapperName, M);<br>+  WrapperFn->setVisibility(WrapperVisibility);<br>+<br>+  auto *EntryBlock = BasicBlock::Create(M.getContext(), "entry", WrapperFn);<br>+  IRBuilder<> IB(EntryBlock);<br>+<br>+  std::vector<Value *> HelperArgs;<br>+  for (auto *Arg : HelperPrefixArgs)<br>+    HelperArgs.push_back(Arg);<br>+  for (auto &Arg : WrapperFn->args())<br>+    HelperArgs.push_back(&Arg);<br>+  auto *HelperResult = IB.CreateCall(HelperFn, HelperArgs);<br>+  if (HelperFn->getReturnType()->isVoidTy())<br>+    IB.CreateRetVoid();<br>+  else<br>+    IB.CreateRet(HelperResult);<br>+<br>+  return WrapperFn;<br>+}<br>+<br>+class GenericLLVMIRPlatformSupport;<br>+<br>+/// orc::Platform component of Generic LLVM IR Platform support.<br>+/// Just forwards calls to the GenericLLVMIRPlatformSupport class below.<br>+class GenericLLVMIRPlatform : public Platform {<br>+public:<br>+  GenericLLVMIRPlatform(GenericLLVMIRPlatformSupport &S) : S(S) {}<br>+  Error setupJITDylib(JITDylib &JD) override;<br>+  Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) override;<br>+  Error notifyRemoving(JITDylib &JD, VModuleKey K) override {<br>+    // Noop -- Nothing to do (yet).<br>+    return Error::success();<br>+  }<br>+<br>+private:<br>+  GenericLLVMIRPlatformSupport &S;<br>+};<br>+<br>+/// This transform parses llvm.global_ctors to produce a single initialization<br>+/// function for the module, records the function, then deletes<br>+/// llvm.global_ctors.<br>+class GlobalCtorDtorScraper {<br>+public:<br>+  GlobalCtorDtorScraper(GenericLLVMIRPlatformSupport &PS) : PS(PS) {}<br>+  Expected<ThreadSafeModule> operator()(ThreadSafeModule TSM,<br>+                                        MaterializationResponsibility &R);<br>+<br>+private:<br>+  GenericLLVMIRPlatformSupport &PS;<br>+};<br>+<br>+/// Generic IR Platform Support<br>+///<br>+/// Scrapes llvm.global_ctors and llvm.global_dtors and replaces them with<br>+/// specially named 'init' and 'deinit'. Injects definitions / interposes for<br>+/// some runtime API, including __cxa_atexit, dlopen, and dlclose.<br>+class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport {<br>+public:<br>+  // GenericLLVMIRPlatform &P) : P(P) {<br>+  GenericLLVMIRPlatformSupport(LLJIT &J) : J(J) {<br>+<br>+    getExecutionSession().setPlatform(<br>+        std::make_unique<GenericLLVMIRPlatform>(*this));<br>+<br>+    setInitTransform(J, GlobalCtorDtorScraper(*this));<br>+<br>+    MangleAndInterner Mangle(getExecutionSession(), J.getDataLayout());<br>+    SymbolMap StdInterposes;<br>+<br>+    StdInterposes[Mangle("__lljit.platform_support_instance")] =<br>+        JITEvaluatedSymbol(pointerToJITTargetAddress(this), JITSymbolFlags());<br>+    StdInterposes[Mangle("__lljit.cxa_atexit_helper")] = JITEvaluatedSymbol(<br>+        pointerToJITTargetAddress(registerAtExitHelper), JITSymbolFlags());<br>+    StdInterposes[Mangle("__lljit.run_atexits_helper")] = JITEvaluatedSymbol(<br>+        pointerToJITTargetAddress(runAtExitsHelper), JITSymbolFlags());<br>+<br>+    cantFail(<br>+        J.getMainJITDylib().define(absoluteSymbols(std::move(StdInterposes))));<br>+    cantFail(setupJITDylib(J.getMainJITDylib()));<br>+    cantFail(J.addIRModule(J.getMainJITDylib(), createPlatformRuntimeModule()));<br>+  }<br>+<br>+  ExecutionSession &getExecutionSession() { return J.getExecutionSession(); }<br>+<br>+  /// Adds a module that defines the __dso_handle global.<br>+  Error setupJITDylib(JITDylib &JD) {<br>+    auto Ctx = std::make_unique<LLVMContext>();<br>+    auto M = std::make_unique<Module>("__standard_lib", *Ctx);<br>+    M->setDataLayout(J.getDataLayout());<br>+<br>+    auto *Int64Ty = Type::getInt64Ty(*Ctx);<br>+    auto *DSOHandle = new GlobalVariable(<br>+        *M, Int64Ty, true, GlobalValue::ExternalLinkage,<br>+        ConstantInt::get(Int64Ty, reinterpret_cast<uintptr_t>(&JD)),<br>+        "__dso_handle");<br>+    DSOHandle->setVisibility(GlobalValue::HiddenVisibility);<br>+    DSOHandle->setInitializer(<br>+        ConstantInt::get(Int64Ty, pointerToJITTargetAddress(&JD)));<br>+    return J.addIRModule(JD, ThreadSafeModule(std::move(M), std::move(Ctx)));<br>+  }<br>+<br>+  Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) {<br>+    std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+    if (auto &InitSym = MU.getInitializerSymbol())<br>+      InitSymbols[&JD].add(InitSym);<br>+    return Error::success();<br>+  }<br>+<br>+  Error initialize(JITDylib &JD) override {<br>+    if (auto Initializers = getInitializers(JD)) {<br>+      for (auto InitFnAddr : *Initializers) {<br>+        auto *InitFn = jitTargetAddressToFunction<void (*)()>(InitFnAddr);<br>+        InitFn();<br>+      }<br>+    } else<br>+      return Initializers.takeError();<br>+    return Error::success();<br>+  }<br>+<br>+  Error deinitialize(JITDylib &JD) override {<br>+    if (auto Deinitializers = getDeinitializers(JD)) {<br>+      for (auto DeinitFnAddr : *Deinitializers) {<br>+        auto *DeinitFn = jitTargetAddressToFunction<void (*)()>(DeinitFnAddr);<br>+        DeinitFn();<br>+      }<br>+    } else<br>+      return Deinitializers.takeError();<br>+<br>+    return Error::success();<br>+  }<br>+<br>+  void registerInitFunc(JITDylib &JD, SymbolStringPtr InitName) {<br>+    std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+    InitFunctions[&JD].add(InitName);<br>+  }<br>+<br>+private:<br>+  Expected<std::vector<JITTargetAddress>> getInitializers(JITDylib &JD) {<br>+    if (auto Err = issueInitLookups(JD))<br>+      return std::move(Err);<br>+<br>+    DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols;<br>+    std::vector<JITDylib *> DFSLinkOrder;<br>+<br>+    {<br>+      std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+      DFSLinkOrder = getDFSLinkOrder(JD);<br>+<br>+      for (auto *NextJD : DFSLinkOrder) {<br>+        auto IFItr = InitFunctions.find(NextJD);<br>+        if (IFItr != InitFunctions.end()) {<br>+          LookupSymbols[NextJD] = std::move(IFItr->second);<br>+          InitFunctions.erase(IFItr);<br>+        }<br>+      }<br>+    }<br>+<br>+    auto &ES = getExecutionSession();<br>+    auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols);<br>+<br>+    if (!LookupResult)<br>+      return LookupResult.takeError();<br>+<br>+    std::vector<JITTargetAddress> Initializers;<br>+    while (!DFSLinkOrder.empty()) {<br>+      auto &NextJD = *DFSLinkOrder.back();<br>+      DFSLinkOrder.pop_back();<br>+      auto InitsItr = LookupResult->find(&NextJD);<br>+      if (InitsItr == LookupResult->end())<br>+        continue;<br>+      for (auto &KV : InitsItr->second)<br>+        Initializers.push_back(KV.second.getAddress());<br>+    }<br>+<br>+    return Initializers;<br>+  }<br>+<br>+  Expected<std::vector<JITTargetAddress>> getDeinitializers(JITDylib &JD) {<br>+    auto &ES = getExecutionSession();<br>+<br>+    MangleAndInterner Mangle(getExecutionSession(), J.getDataLayout());<br>+    auto LLJITRunAtExits = Mangle("__lljit_run_atexits");<br>+<br>+    DenseMap<JITDylib *, SymbolLookupSet> LookupSymbols;<br>+    std::vector<JITDylib *> DFSLinkOrder;<br>+<br>+    {<br>+      std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+      DFSLinkOrder = getDFSLinkOrder(JD);<br>+<br>+      for (auto *NextJD : DFSLinkOrder) {<br>+        auto &JDLookupSymbols = LookupSymbols[NextJD];<br>+        auto DIFItr = DeInitFunctions.find(NextJD);<br>+        if (DIFItr != DeInitFunctions.end()) {<br>+          LookupSymbols[NextJD] = std::move(DIFItr->second);<br>+          DeInitFunctions.erase(DIFItr);<br>+        }<br>+        JDLookupSymbols.add(LLJITRunAtExits,<br>+                            SymbolLookupFlags::WeaklyReferencedSymbol);<br>+      }<br>+    }<br>+<br>+    auto LookupResult = Platform::lookupInitSymbols(ES, LookupSymbols);<br>+<br>+    if (!LookupResult)<br>+      return LookupResult.takeError();<br>+<br>+    std::vector<JITTargetAddress> DeInitializers;<br>+    for (auto *NextJD : DFSLinkOrder) {<br>+      auto DeInitsItr = LookupResult->find(NextJD);<br>+      assert(DeInitsItr != LookupResult->end() &&<br>+             "Every JD should have at least __lljit_run_atexits");<br>+<br>+      auto RunAtExitsItr = DeInitsItr->second.find(LLJITRunAtExits);<br>+      if (RunAtExitsItr != DeInitsItr->second.end())<br>+        DeInitializers.push_back(RunAtExitsItr->second.getAddress());<br>+<br>+      for (auto &KV : DeInitsItr->second)<br>+        if (KV.first != LLJITRunAtExits)<br>+          DeInitializers.push_back(KV.second.getAddress());<br>+    }<br>+<br>+    return DeInitializers;<br>+  }<br>+<br>+  // Returns a DFS traversal order of the JITDylibs reachable (via<br>+  // links-against edges) from JD, starting with JD itself.<br>+  static std::vector<JITDylib *> getDFSLinkOrder(JITDylib &JD) {<br>+    std::vector<JITDylib *> DFSLinkOrder;<br>+    std::vector<JITDylib *> WorkStack({&JD});<br>+    DenseSet<JITDylib *> Visited;<br>+<br>+    while (!WorkStack.empty()) {<br>+      auto &NextJD = *WorkStack.back();<br>+      WorkStack.pop_back();<br>+      if (Visited.count(&NextJD))<br>+        continue;<br>+      Visited.insert(&NextJD);<br>+      DFSLinkOrder.push_back(&NextJD);<br>+      NextJD.withSearchOrderDo([&](const JITDylibSearchOrder &SearchOrder) {<br>+        for (auto &KV : SearchOrder)<br>+          WorkStack.push_back(KV.first);<br>+      });<br>+    }<br>+<br>+    return DFSLinkOrder;<br>+  }<br>+<br>+  /// Issue lookups for all init symbols required to initialize JD (and any<br>+  /// JITDylibs that it depends on).<br>+  Error issueInitLookups(JITDylib &JD) {<br>+    DenseMap<JITDylib *, SymbolLookupSet> RequiredInitSymbols;<br>+<br>+    {<br>+      std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+<br>+      auto DFSLinkOrder = getDFSLinkOrder(JD);<br>+<br>+      for (auto *NextJD : DFSLinkOrder) {<br>+        auto ISItr = InitSymbols.find(NextJD);<br>+        if (ISItr != InitSymbols.end()) {<br>+          RequiredInitSymbols[NextJD] = std::move(ISItr->second);<br>+          InitSymbols.erase(ISItr);<br>+        }<br>+      }<br>+    }<br>+<br>+    return Platform::lookupInitSymbols(getExecutionSession(),<br>+                                       RequiredInitSymbols)<br>+        .takeError();<br>+  }<br>+<br>+  static void registerAtExitHelper(void *Self, void (*F)(void *), void *Ctx,<br>+                                   void *DSOHandle) {<br>+    static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.registerAtExit(<br>+        F, Ctx, DSOHandle);<br>+  }<br>+<br>+  static void runAtExitsHelper(void *Self, void *DSOHandle) {<br>+    static_cast<GenericLLVMIRPlatformSupport *>(Self)->AtExitMgr.runAtExits(<br>+        DSOHandle);<br>+  }<br>+<br>+  // Constructs an LLVM IR module containing platform runtime globals,<br>+  // functions, and interposes.<br>+  ThreadSafeModule createPlatformRuntimeModule() {<br>+    auto Ctx = std::make_unique<LLVMContext>();<br>+    auto M = std::make_unique<Module>("__standard_lib", *Ctx);<br>+    M->setDataLayout(J.getDataLayout());<br>+<br>+    auto *GenericIRPlatformSupportTy =<br>+        StructType::create(*Ctx, "lljit.GenericLLJITIRPlatformSupport");<br>+<br>+    auto *PlatformInstanceDecl = new GlobalVariable(<br>+        *M, GenericIRPlatformSupportTy, true, GlobalValue::ExternalLinkage,<br>+        nullptr, "__lljit.platform_support_instance");<br>+<br>+    auto *DSOHandleDecl = addDSOHandleDecl(*M);<br>+<br>+    auto *Int8Ty = Type::getInt8Ty(*Ctx);<br>+    auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT);<br>+    auto *VoidTy = Type::getVoidTy(*Ctx);<br>+    auto *BytePtrTy = PointerType::getUnqual(Int8Ty);<br>+    auto *AtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false);<br>+    auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy);<br>+<br>+    addHelperAndWrapper(<br>+        *M, "__cxa_atexit",<br>+        FunctionType::get(IntTy, {AtExitCallbackPtrTy, BytePtrTy, BytePtrTy},<br>+                          false),<br>+        GlobalValue::HiddenVisibility, "__lljit.cxa_atexit_helper",<br>+        {PlatformInstanceDecl});<br>+<br>+    addHelperAndWrapper(<br>+        *M, "__lljit_run_atexits", FunctionType::get(VoidTy, {}, false),<br>+        GlobalValue::HiddenVisibility, "__lljit.run_atexits_helper",<br>+        {PlatformInstanceDecl, DSOHandleDecl});<br>+<br>+    return ThreadSafeModule(std::move(M), std::move(Ctx));<br>+  }<br>+<br>+  std::mutex PlatformSupportMutex;<br>+  LLJIT &J;<br>+  DenseMap<JITDylib *, SymbolLookupSet> InitSymbols;<br>+  DenseMap<JITDylib *, SymbolLookupSet> InitFunctions;<br>+  DenseMap<JITDylib *, SymbolLookupSet> DeInitFunctions;<br>+  ItaniumCXAAtExitSupport AtExitMgr;<br>+};<br>+<br>+Error GenericLLVMIRPlatform::setupJITDylib(JITDylib &JD) {<br>+  return S.setupJITDylib(JD);<br>+}<br>+<br>+Error GenericLLVMIRPlatform::notifyAdding(JITDylib &JD,<br>+                                          const MaterializationUnit &MU) {<br>+  return S.notifyAdding(JD, MU);<br>+}<br>+<br>+Expected<ThreadSafeModule><br>+GlobalCtorDtorScraper::operator()(ThreadSafeModule TSM,<br>+                                  MaterializationResponsibility &R) {<br>+  auto Err = TSM.withModuleDo([&](Module &M) -> Error {<br>+    auto &Ctx = M.getContext();<br>+    auto *GlobalCtors = M.getNamedGlobal("llvm.global_ctors");<br>+<br>+    // If there's no llvm.global_ctors or it's just a decl then skip.<br>+    if (!GlobalCtors || GlobalCtors->isDeclaration())<br>+      return Error::success();<br>+<br>+    std::string InitFunctionName;<br>+    raw_string_ostream(InitFunctionName)<br>+        << "__orc_init." << M.getModuleIdentifier();<br>+<br>+    MangleAndInterner Mangle(PS.getExecutionSession(), M.getDataLayout());<br>+    auto InternedName = Mangle(InitFunctionName);<br>+    if (auto Err =<br>+            R.defineMaterializing({{InternedName, JITSymbolFlags::Callable}}))<br>+      return Err;<br>+<br>+    auto *InitFunc =<br>+        Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {}, false),<br>+                         GlobalValue::ExternalLinkage, InitFunctionName, &M);<br>+    InitFunc->setVisibility(GlobalValue::HiddenVisibility);<br>+    std::vector<std::pair<Function *, unsigned>> Inits;<br>+    for (auto E : getConstructors(M))<br>+      Inits.push_back(std::make_pair(E.Func, E.Priority));<br>+    llvm::sort(Inits, [](const std::pair<Function *, unsigned> &LHS,<br>+                         const std::pair<Function *, unsigned> &RHS) {<br>+      return LHS.first < RHS.first;<br>+    });<br>+    auto *EntryBlock = BasicBlock::Create(Ctx, "entry", InitFunc);<br>+    IRBuilder<> IB(EntryBlock);<br>+    for (auto &KV : Inits)<br>+      IB.CreateCall(KV.first);<br>+    IB.CreateRetVoid();<br>+<br>+    PS.registerInitFunc(R.getTargetJITDylib(), InternedName);<br>+    GlobalCtors->eraseFromParent();<br>+    return Error::success();<br>+  });<br>+<br>+  if (Err)<br>+    return std::move(Err);<br>+<br>+  return TSM;<br>+}<br>+<br>+class MachOPlatformSupport : public LLJIT::PlatformSupport {<br>+public:<br>+  using DLOpenType = void *(*)(const char *Name, int Mode);<br>+  using DLCloseType = int (*)(void *Handle);<br>+  using DLSymType = void *(*)(void *Handle, const char *Name);<br>+  using DLErrorType = const char *(*)();<br>+<br>+  struct DlFcnValues {<br>+    Optional<void *> RTLDDefault;<br>+    DLOpenType dlopen = nullptr;<br>+    DLCloseType dlclose = nullptr;<br>+    DLSymType dlsym = nullptr;<br>+    DLErrorType dlerror = nullptr;<br>+  };<br>+<br>+  static Expected<std::unique_ptr<MachOPlatformSupport>><br>+  Create(LLJIT &J, JITDylib &PlatformJITDylib) {<br>+<br>+    // Make process symbols visible.<br>+    {<br>+      std::string ErrMsg;<br>+      auto Lib = sys::DynamicLibrary::getPermanentLibrary(nullptr, &ErrMsg);<br>+      if (!Lib.isValid())<br>+        return make_error<StringError>(std::move(ErrMsg),<br>+                                       inconvertibleErrorCode());<br>+    }<br>+<br>+    DlFcnValues DlFcn;<br>+<br>+    // Add support for RTLDDefault on known platforms.<br>+#ifdef __APPLE__<br>+    DlFcn.RTLDDefault = reinterpret_cast<void *>(-2);<br>+#endif // __APPLE__<br>+<br>+    if (auto Err = hookUpFunction(DlFcn.dlopen, "dlopen"))<br>+      return std::move(Err);<br>+    if (auto Err = hookUpFunction(DlFcn.dlclose, "dlclose"))<br>+      return std::move(Err);<br>+    if (auto Err = hookUpFunction(DlFcn.dlsym, "dlsym"))<br>+      return std::move(Err);<br>+    if (auto Err = hookUpFunction(DlFcn.dlerror, "dlerror"))<br>+      return std::move(Err);<br>+<br>+    std::unique_ptr<MachOPlatformSupport> MP(<br>+        new MachOPlatformSupport(J, PlatformJITDylib, DlFcn));<br>+    return std::move(MP);<br>+  }<br>+<br>+  Error initialize(JITDylib &JD) override {<br>+    if (auto InitSeq = MP.getInitializerSequence(JD)) {<br>+      for (auto &KV : *InitSeq) {<br>+        KV.second.registerObjCSelectors();<br>+        if (auto Err = KV.second.registerObjCClasses()) {<br>+          // FIXME: Roll back registrations on error?<br>+          return Err;<br>+        }<br>+      }<br>+      for (auto &KV : *InitSeq)<br>+        KV.second.runModInits();<br>+    } else<br>+      return InitSeq.takeError();<br>+    return Error::success();<br>+  }<br>+<br>+  Error deinitialize(JITDylib &JD) override {<br>+    auto &ES = J.getExecutionSession();<br>+    if (auto DeinitSeq = MP.getDeinitializerSequence(JD)) {<br>+      for (auto &KV : *DeinitSeq) {<br>+        auto DSOHandleName = ES.intern("___dso_handle");<br>+<br>+        // FIXME: Run DeInits here.<br>+        auto Result = ES.lookup(<br>+            {{KV.first, JITDylibLookupFlags::MatchAllSymbols}},<br>+            SymbolLookupSet(DSOHandleName,<br>+                            SymbolLookupFlags::WeaklyReferencedSymbol));<br>+        if (!Result)<br>+          return Result.takeError();<br>+        if (Result->empty())<br>+          continue;<br>+        assert(Result->count(DSOHandleName) &&<br>+               "Result does not contain __dso_handle");<br>+        auto *DSOHandle = jitTargetAddressToPointer<void *>(<br>+            Result->begin()->second.getAddress());<br>+        AtExitMgr.runAtExits(DSOHandle);<br>+      }<br>+    } else<br>+      return DeinitSeq.takeError();<br>+    return Error::success();<br>+  }<br>+<br>+private:<br>+  template <typename FunctionPtrTy><br>+  static Error hookUpFunction(FunctionPtrTy &Fn, const char *Name) {<br>+    if (auto *FnAddr = sys::DynamicLibrary::SearchForAddressOfSymbol(Name)) {<br>+      Fn = reinterpret_cast<FunctionPtrTy>(Fn);<br>+      return Error::success();<br>+    }<br>+<br>+    return make_error<StringError>((Twine("Can not enable MachO JIT Platform: "<br>+                                          "missing function: ") +<br>+                                    Name)<br>+                                       .str(),<br>+                                   inconvertibleErrorCode());<br>+  }<br>+<br>+  MachOPlatformSupport(LLJIT &J, JITDylib &PlatformJITDylib, DlFcnValues DlFcn)<br>+      : J(J), MP(setupPlatform(J)), DlFcn(std::move(DlFcn)) {<br>+<br>+    MangleAndInterner Mangle(J.getExecutionSession(), J.getDataLayout());<br>+    SymbolMap HelperSymbols;<br>+<br>+    // platform and atexit helpers.<br>+    HelperSymbols[Mangle("__lljit.platform_support_instance")] =<br>+        JITEvaluatedSymbol(pointerToJITTargetAddress(this), JITSymbolFlags());<br>+    HelperSymbols[Mangle("__lljit.cxa_atexit_helper")] = JITEvaluatedSymbol(<br>+        pointerToJITTargetAddress(registerAtExitHelper), JITSymbolFlags());<br>+    HelperSymbols[Mangle("__lljit.run_atexits_helper")] = JITEvaluatedSymbol(<br>+        pointerToJITTargetAddress(runAtExitsHelper), JITSymbolFlags());<br>+<br>+    // dlfcn helpers.<br>+    HelperSymbols[Mangle("__lljit.dlopen_helper")] = JITEvaluatedSymbol(<br>+        pointerToJITTargetAddress(dlopenHelper), JITSymbolFlags());<br>+    HelperSymbols[Mangle("__lljit.dlclose_helper")] = JITEvaluatedSymbol(<br>+        pointerToJITTargetAddress(dlcloseHelper), JITSymbolFlags());<br>+    HelperSymbols[Mangle("__lljit.dlsym_helper")] = JITEvaluatedSymbol(<br>+        pointerToJITTargetAddress(dlsymHelper), JITSymbolFlags());<br>+    HelperSymbols[Mangle("__lljit.dlerror_helper")] = JITEvaluatedSymbol(<br>+        pointerToJITTargetAddress(dlerrorHelper), JITSymbolFlags());<br>+<br>+    cantFail(<br>+        PlatformJITDylib.define(absoluteSymbols(std::move(HelperSymbols))));<br>+    cantFail(MP.setupJITDylib(J.getMainJITDylib()));<br>+    cantFail(J.addIRModule(PlatformJITDylib, createPlatformRuntimeModule()));<br>+  }<br>+<br>+  static MachOPlatform &setupPlatform(LLJIT &J) {<br>+    auto Tmp = std::make_unique<MachOPlatform>(<br>+        J.getExecutionSession(),<br>+        static_cast<ObjectLinkingLayer &>(J.getObjLinkingLayer()),<br>+        createStandardSymbolsObject(J));<br>+    auto &MP = *Tmp;<br>+    J.getExecutionSession().setPlatform(std::move(Tmp));<br>+    return MP;<br>+  }<br>+<br>+  static std::unique_ptr<MemoryBuffer> createStandardSymbolsObject(LLJIT &J) {<br>+    LLVMContext Ctx;<br>+    Module M("__standard_symbols", Ctx);<br>+    M.setDataLayout(J.getDataLayout());<br>+<br>+    auto *Int64Ty = Type::getInt64Ty(Ctx);<br>+<br>+    auto *DSOHandle =<br>+        new GlobalVariable(M, Int64Ty, true, GlobalValue::ExternalLinkage,<br>+                           ConstantInt::get(Int64Ty, 0), "__dso_handle");<br>+    DSOHandle->setVisibility(GlobalValue::HiddenVisibility);<br>+<br>+    return cantFail(J.getIRCompileLayer().getCompiler()(M));<br>+  }<br>+<br>+  ThreadSafeModule createPlatformRuntimeModule() {<br>+    auto Ctx = std::make_unique<LLVMContext>();<br>+    auto M = std::make_unique<Module>("__standard_lib", *Ctx);<br>+    M->setDataLayout(J.getDataLayout());<br>+<br>+    auto *MachOPlatformSupportTy =<br>+        StructType::create(*Ctx, "lljit.MachOPlatformSupport");<br>+<br>+    auto *PlatformInstanceDecl = new GlobalVariable(<br>+        *M, MachOPlatformSupportTy, true, GlobalValue::ExternalLinkage, nullptr,<br>+        "__lljit.platform_support_instance");<br>+<br>+    auto *Int8Ty = Type::getInt8Ty(*Ctx);<br>+    auto *IntTy = Type::getIntNTy(*Ctx, sizeof(int) * CHAR_BIT);<br>+    auto *VoidTy = Type::getVoidTy(*Ctx);<br>+    auto *BytePtrTy = PointerType::getUnqual(Int8Ty);<br>+    auto *AtExitCallbackTy = FunctionType::get(VoidTy, {BytePtrTy}, false);<br>+    auto *AtExitCallbackPtrTy = PointerType::getUnqual(AtExitCallbackTy);<br>+<br>+    addHelperAndWrapper(<br>+        *M, "__cxa_atexit",<br>+        FunctionType::get(IntTy, {AtExitCallbackPtrTy, BytePtrTy, BytePtrTy},<br>+                          false),<br>+        GlobalValue::DefaultVisibility, "__lljit.cxa_atexit_helper",<br>+        {PlatformInstanceDecl});<br>+<br>+    addHelperAndWrapper(*M, "dlopen",<br>+                        FunctionType::get(BytePtrTy, {BytePtrTy, IntTy}, false),<br>+                        GlobalValue::DefaultVisibility, "__lljit.dlopen_helper",<br>+                        {PlatformInstanceDecl});<br>+<br>+    addHelperAndWrapper(*M, "dlclose",<br>+                        FunctionType::get(IntTy, {BytePtrTy}, false),<br>+                        GlobalValue::DefaultVisibility,<br>+                        "__lljit.dlclose_helper", {PlatformInstanceDecl});<br>+<br>+    addHelperAndWrapper(<br>+        *M, "dlsym",<br>+        FunctionType::get(BytePtrTy, {BytePtrTy, BytePtrTy}, false),<br>+        GlobalValue::DefaultVisibility, "__lljit.dlsym_helper",<br>+        {PlatformInstanceDecl});<br>+<br>+    addHelperAndWrapper(*M, "dlerror", FunctionType::get(BytePtrTy, {}, false),<br>+                        GlobalValue::DefaultVisibility,<br>+                        "__lljit.dlerror_helper", {PlatformInstanceDecl});<br>+<br>+    return ThreadSafeModule(std::move(M), std::move(Ctx));<br>+  }<br>+<br>+  static void registerAtExitHelper(void *Self, void (*F)(void *), void *Ctx,<br>+                                   void *DSOHandle) {<br>+    static_cast<MachOPlatformSupport *>(Self)->AtExitMgr.registerAtExit(<br>+        F, Ctx, DSOHandle);<br>+  }<br>+<br>+  static void runAtExitsHelper(void *Self, void *DSOHandle) {<br>+    static_cast<MachOPlatformSupport *>(Self)->AtExitMgr.runAtExits(DSOHandle);<br>+  }<br>+<br>+  void *jit_dlopen(const char *Path, int Mode) {<br>+    JITDylib *JDToOpen = nullptr;<br>+    // FIXME: Do the right thing with Mode flags.<br>+    {<br>+      std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+<br>+      // Clear any existing error messages.<br>+      dlErrorMsgs.erase(std::this_thread::get_id());<br>+<br>+      if (auto *JD = J.getExecutionSession().getJITDylibByName(Path)) {<br>+        auto I = JDRefCounts.find(JD);<br>+        if (I != JDRefCounts.end()) {<br>+          ++I->second;<br>+          return JD;<br>+        }<br>+<br>+        JDRefCounts[JD] = 1;<br>+        JDToOpen = JD;<br>+      }<br>+    }<br>+<br>+    if (JDToOpen) {<br>+      if (auto Err = initialize(*JDToOpen)) {<br>+        recordError(std::move(Err));<br>+        return 0;<br>+      }<br>+    }<br>+<br>+    // Fall through to dlopen if no JITDylib found for Path.<br>+    return DlFcn.dlopen(Path, Mode);<br>+  }<br>+<br>+  static void *dlopenHelper(void *Self, const char *Path, int Mode) {<br>+    return static_cast<MachOPlatformSupport *>(Self)->jit_dlopen(Path, Mode);<br>+  }<br>+<br>+  int jit_dlclose(void *Handle) {<br>+    JITDylib *JDToClose = nullptr;<br>+<br>+    {<br>+      std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+<br>+      // Clear any existing error messages.<br>+      dlErrorMsgs.erase(std::this_thread::get_id());<br>+<br>+      auto I = JDRefCounts.find(Handle);<br>+      if (I != JDRefCounts.end()) {<br>+        --I->second;<br>+        if (I->second == 0) {<br>+          JDRefCounts.erase(I);<br>+          JDToClose = static_cast<JITDylib *>(Handle);<br>+        } else<br>+          return 0;<br>+      }<br>+    }<br>+<br>+    if (JDToClose) {<br>+      if (auto Err = deinitialize(*JDToClose)) {<br>+        recordError(std::move(Err));<br>+        return -1;<br>+      }<br>+      return 0;<br>+    }<br>+<br>+    // Fall through to dlclose if no JITDylib found for Path.<br>+    return DlFcn.dlclose(Handle);<br>+  }<br>+<br>+  static int dlcloseHelper(void *Self, void *Handle) {<br>+    return static_cast<MachOPlatformSupport *>(Self)->jit_dlclose(Handle);<br>+  }<br>+<br>+  void *jit_dlsym(void *Handle, const char *Name) {<br>+    JITDylibSearchOrder JITSymSearchOrder;<br>+<br>+    // FIXME: RTLD_NEXT, RTLD_SELF not supported.<br>+    {<br>+      std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+<br>+      // Clear any existing error messages.<br>+      dlErrorMsgs.erase(std::this_thread::get_id());<br>+<br>+      if (JDRefCounts.count(Handle)) {<br>+        JITSymSearchOrder.push_back(<br>+            {static_cast<JITDylib *>(Handle),<br>+             JITDylibLookupFlags::MatchExportedSymbolsOnly});<br>+      } else if (Handle == DlFcn.RTLDDefault) {<br>+        for (auto &KV : JDRefCounts)<br>+          JITSymSearchOrder.push_back(<br>+              {static_cast<JITDylib *>(KV.first),<br>+               JITDylibLookupFlags::MatchExportedSymbolsOnly});<br>+      }<br>+    }<br>+<br>+    if (!JITSymSearchOrder.empty()) {<br>+      MangleAndInterner Mangle(J.getExecutionSession(), J.getDataLayout());<br>+      auto MangledName = Mangle(Name);<br>+      SymbolLookupSet Syms(MangledName,<br>+                           SymbolLookupFlags::WeaklyReferencedSymbol);<br>+      if (auto Result = J.getExecutionSession().lookup(JITSymSearchOrder, Syms,<br>+                                                       LookupKind::DLSym)) {<br>+        auto I = Result->find(MangledName);<br>+        if (I != Result->end())<br>+          return jitTargetAddressToPointer<void *>(I->second.getAddress());<br>+      } else {<br>+        recordError(Result.takeError());<br>+        return 0;<br>+      }<br>+    }<br>+<br>+    // Fall through to dlsym.<br>+    return DlFcn.dlsym(Handle, Name);<br>+  }<br>+<br>+  static void *dlsymHelper(void *Self, void *Handle, const char *Name) {<br>+    return static_cast<MachOPlatformSupport *>(Self)->jit_dlsym(Handle, Name);<br>+  }<br>+<br>+  const char *jit_dlerror() {<br>+    {<br>+      std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+      auto I = dlErrorMsgs.find(std::this_thread::get_id());<br>+      if (I != dlErrorMsgs.end())<br>+        return I->second->c_str();<br>+    }<br>+    return DlFcn.dlerror();<br>+  }<br>+<br>+  static const char *dlerrorHelper(void *Self) {<br>+    return static_cast<MachOPlatformSupport *>(Self)->jit_dlerror();<br>+  }<br>+<br>+  void recordError(Error Err) {<br>+    std::lock_guard<std::mutex> Lock(PlatformSupportMutex);<br>+    dlErrorMsgs[std::this_thread::get_id()] =<br>+        std::make_unique<std::string>(toString(std::move(Err)));<br>+  }<br>+<br>+  std::mutex PlatformSupportMutex;<br>+  LLJIT &J;<br>+  MachOPlatform &MP;<br>+  DlFcnValues DlFcn;<br>+  ItaniumCXAAtExitSupport AtExitMgr;<br>+  DenseMap<void *, unsigned> JDRefCounts;<br>+  std::map<std::thread::id, std::unique_ptr<std::string>> dlErrorMsgs;<br>+};<br>+<br>+} // end anonymous namespace<br><br> namespace llvm {<br> namespace orc {<br><br>+void LLJIT::PlatformSupport::setInitTransform(<br>+    LLJIT &J, IRTransformLayer::TransformFunction T) {<br>+  J.InitHelperTransformLayer->setTransform(std::move(T));<br>+}<br>+<br>+LLJIT::PlatformSupport::~PlatformSupport() {}<br>+<br> Error LLJITBuilderState::prepareForConstruction() {<br><br>   if (!JTMB) {<br>@@ -57,7 +869,7 @@ LLJIT::~LLJIT() {<br> Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {<br>   auto InternedName = ES->intern(Name);<br>   SymbolMap Symbols({{InternedName, Sym}});<br>-  return Main.define(absoluteSymbols(std::move(Symbols)));<br>+  return Main->define(absoluteSymbols(std::move(Symbols)));<br> }<br><br> Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {<br>@@ -67,7 +879,8 @@ Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {<br>           TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); }))<br>     return Err;<br><br>-  return TransformLayer->add(JD, std::move(TSM), ES->allocateVModule());<br>+  return InitHelperTransformLayer->add(JD, std::move(TSM),<br>+                                       ES->allocateVModule());<br> }<br><br> Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {<br>@@ -128,16 +941,23 @@ LLJIT::createCompileFunction(LLJITBuilderState &S,<br> }<br><br> LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)<br>-    : ES(<a href="http://S.ES" target="_blank">S.ES</a> ? std::move(<a href="http://S.ES" target="_blank">S.ES</a>) : std::make_unique<ExecutionSession>()),<br>-      Main(this->ES->createJITDylib("<main>")), DL(""),<br>-      TT(S.JTMB->getTargetTriple()),<br>+    : ES(<a href="http://S.ES" target="_blank">S.ES</a> ? std::move(<a href="http://S.ES" target="_blank">S.ES</a>) : std::make_unique<ExecutionSession>()), Main(),<br>+      DL(""), TT(S.JTMB->getTargetTriple()),<br>       ObjLinkingLayer(createObjectLinkingLayer(S, *ES)),<br>-      ObjTransformLayer(*this->ES, *ObjLinkingLayer), CtorRunner(Main),<br>-      DtorRunner(Main) {<br>+      ObjTransformLayer(*this->ES, *ObjLinkingLayer) {<br><br>   ErrorAsOutParameter _(&Err);<br><br>-  if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())<br>+  if (auto MainOrErr = this->ES->createJITDylib("main"))<br>+    Main = &*MainOrErr;<br>+  else {<br>+    Err = MainOrErr.takeError();<br>+    return;<br>+  }<br>+<br>+  if (S.DL)<br>+    DL = std::move(*S.DL);<br>+  else if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())<br>     DL = std::move(*DLOrErr);<br>   else {<br>     Err = DLOrErr.takeError();<br>@@ -153,10 +973,12 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)<br>     CompileLayer = std::make_unique<IRCompileLayer>(<br>         *ES, ObjTransformLayer, std::move(*CompileFunction));<br>     TransformLayer = std::make_unique<IRTransformLayer>(*ES, *CompileLayer);<br>+    InitHelperTransformLayer =<br>+        std::make_unique<IRTransformLayer>(*ES, *TransformLayer);<br>   }<br><br>   if (S.NumCompileThreads > 0) {<br>-    TransformLayer->setCloneToNewContextOnEmit(true);<br>+    InitHelperTransformLayer->setCloneToNewContextOnEmit(true);<br>     CompileThreads =<br>         std::make_unique<ThreadPool>(hardware_concurrency(S.NumCompileThreads));<br>     ES->setDispatchMaterialization(<br>@@ -167,6 +989,11 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)<br>           CompileThreads->async(std::move(Work));<br>         });<br>   }<br>+<br>+  if (S.SetUpPlatform)<br>+    Err = S.SetUpPlatform(*this);<br>+  else<br>+    setUpGenericLLVMIRPlatform(*this);<br> }<br><br> std::string LLJIT::mangle(StringRef UnmangledName) {<br>@@ -184,15 +1011,24 @@ Error LLJIT::applyDataLayout(Module &M) {<br><br>   if (M.getDataLayout() != DL)<br>     return make_error<StringError>(<br>-        "Added modules have incompatible data layouts",<br>+        "Added modules have incompatible data layouts: " +<br>+            M.getDataLayout().getStringRepresentation() + " (module) vs " +<br>+            DL.getStringRepresentation() + " (jit)",<br>         inconvertibleErrorCode());<br><br>   return Error::success();<br> }<br><br>-void LLJIT::recordCtorDtors(Module &M) {<br>-  CtorRunner.add(getConstructors(M));<br>-  DtorRunner.add(getDestructors(M));<br>+void setUpGenericLLVMIRPlatform(LLJIT &J) {<br>+  J.setPlatformSupport(std::make_unique<GenericLLVMIRPlatformSupport>(J));<br>+}<br>+<br>+Error setUpMachOPlatform(LLJIT &J) {<br>+  auto MP = MachOPlatformSupport::Create(J, J.getMainJITDylib());<br>+  if (!MP)<br>+    return MP.takeError();<br>+  J.setPlatformSupport(std::move(*MP));<br>+  return Error::success();<br> }<br><br> Error LLLazyJITBuilderState::prepareForConstruction() {<br>@@ -205,13 +1041,8 @@ Error LLLazyJITBuilderState::prepareForConstruction() {<br> Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {<br>   assert(TSM && "Can not add null module");<br><br>-  if (auto Err = TSM.withModuleDo([&](Module &M) -> Error {<br>-        if (auto Err = applyDataLayout(M))<br>-          return Err;<br>-<br>-        recordCtorDtors(M);<br>-        return Error::success();<br>-      }))<br>+  if (auto Err = TSM.withModuleDo(<br>+          [&](Module &M) -> Error { return applyDataLayout(M); }))<br>     return Err;<br><br>   return CODLayer->add(JD, std::move(TSM), ES->allocateVModule());<br>@@ -256,7 +1087,7 @@ LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {<br><br>   // Create the COD layer.<br>   CODLayer = std::make_unique<CompileOnDemandLayer>(<br>-      *ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder));<br>+      *ES, *InitHelperTransformLayer, *LCTMgr, std::move(ISMBuilder));<br><br>   if (S.NumCompileThreads > 0)<br>     CODLayer->setCloneToNewContextOnEmit(true);<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp<br>index ebc7801f11ff..63b04a0562bd 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp<br>@@ -7,7 +7,10 @@<br> //===----------------------------------------------------------------------===//<br><br> #include "llvm/ExecutionEngine/Orc/Layer.h"<br>+<br>+#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"<br> #include "llvm/IR/Constants.h"<br>+#include "llvm/Object/MachO.h"<br> #include "llvm/Object/ObjectFile.h"<br> #include "llvm/Support/Debug.h"<br><br>@@ -23,10 +26,11 @@ Error IRLayer::add(JITDylib &JD, ThreadSafeModule TSM, VModuleKey K) {<br>       *this, *getManglingOptions(), std::move(TSM), std::move(K)));<br> }<br><br>-IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES,<br>-                                             const ManglingOptions &MO,<br>-                                             ThreadSafeModule TSM, VModuleKey K)<br>-    : MaterializationUnit(SymbolFlagsMap(), std::move(K)), TSM(std::move(TSM)) {<br>+IRMaterializationUnit::IRMaterializationUnit(<br>+    ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO,<br>+    ThreadSafeModule TSM, VModuleKey K)<br>+    : MaterializationUnit(SymbolFlagsMap(), nullptr, std::move(K)),<br>+      TSM(std::move(TSM)) {<br><br>   assert(this->TSM && "Module must not be null");<br><br>@@ -34,6 +38,7 @@ IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES,<br>   this->TSM.withModuleDo([&](Module &M) {<br>     for (auto &G : M.global_values()) {<br>       // Skip globals that don't generate symbols.<br>+<br>       if (!G.hasName() || G.isDeclaration() || G.hasLocalLinkage() ||<br>           G.hasAvailableExternallyLinkage() || G.hasAppendingLinkage())<br>         continue;<br>@@ -72,13 +77,23 @@ IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES,<br>       SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G);<br>       SymbolToDefinition[MangledName] = &G;<br>     }<br>+<br>+    // If we need an init symbol for this module then create one.<br>+    if (!llvm::empty(getStaticInitGVs(M))) {<br>+      std::string InitSymbolName;<br>+      raw_string_ostream(InitSymbolName)<br>+          << "$." << M.getModuleIdentifier() << ".__inits";<br>+      InitSymbol = ES.intern(InitSymbolName);<br>+      SymbolFlags[InitSymbol] = JITSymbolFlags();<br>+    }<br>   });<br> }<br><br> IRMaterializationUnit::IRMaterializationUnit(<br>     ThreadSafeModule TSM, VModuleKey K, SymbolFlagsMap SymbolFlags,<br>-    SymbolNameToDefinitionMap SymbolToDefinition)<br>-    : MaterializationUnit(std::move(SymbolFlags), std::move(K)),<br>+    SymbolStringPtr InitSymbol, SymbolNameToDefinitionMap SymbolToDefinition)<br>+    : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol),<br>+                          std::move(K)),<br>       TSM(std::move(TSM)), SymbolToDefinition(std::move(SymbolToDefinition)) {}<br><br> StringRef IRMaterializationUnit::getName() const {<br>@@ -105,7 +120,8 @@ void IRMaterializationUnit::discard(const JITDylib &JD,<br> }<br><br> BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(<br>-    IRLayer &L, const ManglingOptions &MO, ThreadSafeModule TSM, VModuleKey K)<br>+    IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM,<br>+    VModuleKey K)<br>     : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM),<br>                             std::move(K)),<br>       L(L), K(std::move(K)) {}<br>@@ -150,22 +166,26 @@ Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O,<br> Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>><br> BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L, VModuleKey K,<br>                                             std::unique_ptr<MemoryBuffer> O) {<br>-  auto SymbolFlags =<br>-      getObjectSymbolFlags(L.getExecutionSession(), O->getMemBufferRef());<br>+  auto ObjSymInfo =<br>+      getObjectSymbolInfo(L.getExecutionSession(), O->getMemBufferRef());<br>+<br>+  if (!ObjSymInfo)<br>+    return ObjSymInfo.takeError();<br><br>-  if (!SymbolFlags)<br>-    return SymbolFlags.takeError();<br>+  auto &SymbolFlags = ObjSymInfo->first;<br>+  auto &InitSymbol = ObjSymInfo->second;<br><br>   return std::unique_ptr<BasicObjectLayerMaterializationUnit>(<br>-      new BasicObjectLayerMaterializationUnit(L, K, std::move(O),<br>-                                              std::move(*SymbolFlags)));<br>+      new BasicObjectLayerMaterializationUnit(<br>+          L, K, std::move(O), std::move(SymbolFlags), std::move(InitSymbol)));<br> }<br><br> BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit(<br>     ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O,<br>-    SymbolFlagsMap SymbolFlags)<br>-    : MaterializationUnit(std::move(SymbolFlags), std::move(K)), L(L),<br>-      O(std::move(O)) {}<br>+    SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol)<br>+    : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol),<br>+                          std::move(K)),<br>+      L(L), O(std::move(O)) {}<br><br> StringRef BasicObjectLayerMaterializationUnit::getName() const {<br>   if (O)<br>@@ -184,35 +204,5 @@ void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,<br>   //        filter to pass to the object layer along with the object itself.<br> }<br><br>-Expected<SymbolFlagsMap> getObjectSymbolFlags(ExecutionSession &ES,<br>-                                              MemoryBufferRef ObjBuffer) {<br>-  auto Obj = object::ObjectFile::createObjectFile(ObjBuffer);<br>-<br>-  if (!Obj)<br>-    return Obj.takeError();<br>-<br>-  SymbolFlagsMap SymbolFlags;<br>-  for (auto &Sym : (*Obj)->symbols()) {<br>-    // Skip symbols not defined in this object file.<br>-    if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined)<br>-      continue;<br>-<br>-    // Skip symbols that are not global.<br>-    if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global))<br>-      continue;<br>-<br>-    auto Name = Sym.getName();<br>-    if (!Name)<br>-      return Name.takeError();<br>-    auto InternedName = ES.intern(*Name);<br>-    auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);<br>-    if (!SymFlags)<br>-      return SymFlags.takeError();<br>-    SymbolFlags[InternedName] = std::move(*SymFlags);<br>-  }<br>-<br>-  return SymbolFlags;<br>-}<br>-<br> } // End namespace orc.<br> } // End namespace llvm.<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp<br>index 97f36ede713f..27d08e18270f 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp<br>@@ -51,7 +51,7 @@ LazyCallThroughManager::callThroughToSymbol(JITTargetAddress TrampolineAddr) {<br><br>   auto LookupResult = ES.lookup(<br>       makeJITDylibSearchOrder(SourceJD, JITDylibLookupFlags::MatchAllSymbols),<br>-      SymbolName);<br>+      SymbolName, SymbolState::Ready);<br><br>   if (!LookupResult) {<br>     ES.reportError(LookupResult.takeError());<br>@@ -123,10 +123,9 @@ LazyReexportsMaterializationUnit::LazyReexportsMaterializationUnit(<br>     LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager,<br>     JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc,<br>     VModuleKey K)<br>-    : MaterializationUnit(extractFlags(CallableAliases), std::move(K)),<br>+    : MaterializationUnit(extractFlags(CallableAliases), nullptr, std::move(K)),<br>       LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD),<br>-      CallableAliases(std::move(CallableAliases)),<br>-      AliaseeTable(SrcJDLoc) {}<br>+      CallableAliases(std::move(CallableAliases)), AliaseeTable(SrcJDLoc) {}<br><br> StringRef LazyReexportsMaterializationUnit::getName() const {<br>   return "<Lazy Reexports>";<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp<br>new file mode 100644<br>index 000000000000..4618d53315ef<br>--- /dev/null<br>+++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp<br>@@ -0,0 +1,459 @@<br>+//===------ MachOPlatform.cpp - Utilities for executing MachO in Orc ------===//<br>+//<br>+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>+// See <a href="https://llvm.org/LICENSE.txt" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"<br>+<br>+#include "llvm/BinaryFormat/MachO.h"<br>+#include "llvm/Support/BinaryByteStream.h"<br>+<br>+namespace {<br>+<br>+struct objc_class;<br>+struct objc_image_info;<br>+struct objc_object;<br>+struct objc_selector;<br>+<br>+using Class = objc_class *;<br>+using id = objc_object *;<br>+using SEL = objc_selector *;<br>+<br>+using ObjCMsgSendTy = id (*)(id, SEL, ...);<br>+using ObjCReadClassPairTy = Class (*)(Class, const objc_image_info *);<br>+using SelRegisterNameTy = SEL (*)(const char *);<br>+<br>+enum class ObjCRegistrationAPI { Uninitialized, Unavailable, Initialized };<br>+<br>+ObjCRegistrationAPI ObjCRegistrationAPIState =<br>+    ObjCRegistrationAPI::Uninitialized;<br>+ObjCMsgSendTy objc_msgSend = nullptr;<br>+ObjCReadClassPairTy objc_readClassPair = nullptr;<br>+SelRegisterNameTy sel_registerName = nullptr;<br>+<br>+} // end anonymous namespace<br>+<br>+namespace llvm {<br>+namespace orc {<br>+<br>+template <typename FnTy><br>+static Error setUpObjCRegAPIFunc(FnTy &Target, sys::DynamicLibrary &LibObjC,<br>+                                 const char *Name) {<br>+  if (void *Addr = LibObjC.getAddressOfSymbol(Name))<br>+    Target = reinterpret_cast<FnTy>(Addr);<br>+  else<br>+    return make_error<StringError>(<br>+        (Twine("Could not find address for ") + Name).str(),<br>+        inconvertibleErrorCode());<br>+  return Error::success();<br>+}<br>+<br>+Error enableObjCRegistration(const char *PathToLibObjC) {<br>+  // If we've already tried to initialize then just bail out.<br>+  if (ObjCRegistrationAPIState != ObjCRegistrationAPI::Uninitialized)<br>+    return Error::success();<br>+<br>+  ObjCRegistrationAPIState = ObjCRegistrationAPI::Unavailable;<br>+<br>+  std::string ErrMsg;<br>+  auto LibObjC =<br>+      sys::DynamicLibrary::getPermanentLibrary(PathToLibObjC, &ErrMsg);<br>+<br>+  if (!LibObjC.isValid())<br>+    return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());<br>+<br>+  if (auto Err = setUpObjCRegAPIFunc(objc_msgSend, LibObjC, "objc_msgSend"))<br>+    return Err;<br>+  if (auto Err = setUpObjCRegAPIFunc(objc_readClassPair, LibObjC,<br>+                                     "objc_readClassPair"))<br>+    return Err;<br>+  if (auto Err =<br>+          setUpObjCRegAPIFunc(sel_registerName, LibObjC, "sel_registerName"))<br>+    return Err;<br>+<br>+  ObjCRegistrationAPIState = ObjCRegistrationAPI::Initialized;<br>+  return Error::success();<br>+}<br>+<br>+bool objcRegistrationEnabled() {<br>+  return ObjCRegistrationAPIState == ObjCRegistrationAPI::Initialized;<br>+}<br>+<br>+void MachOJITDylibInitializers::runModInits() const {<br>+  for (const auto &ModInit : ModInitSections) {<br>+    for (uint64_t I = 0; I != ModInit.NumPtrs; ++I) {<br>+      auto *InitializerAddr = jitTargetAddressToPointer<uintptr_t *>(<br>+          ModInit.Address + (I * sizeof(uintptr_t)));<br>+      auto *Initializer =<br>+          jitTargetAddressToFunction<void (*)()>(*InitializerAddr);<br>+      Initializer();<br>+    }<br>+  }<br>+}<br>+<br>+void MachOJITDylibInitializers::registerObjCSelectors() const {<br>+  assert(objcRegistrationEnabled() && "ObjC registration not enabled.");<br>+<br>+  for (const auto &ObjCSelRefs : ObjCSelRefsSections) {<br>+    for (uint64_t I = 0; I != ObjCSelRefs.NumPtrs; ++I) {<br>+      auto SelEntryAddr = ObjCSelRefs.Address + (I * sizeof(uintptr_t));<br>+      const auto *SelName =<br>+          *jitTargetAddressToPointer<const char **>(SelEntryAddr);<br>+      auto Sel = sel_registerName(SelName);<br>+      *jitTargetAddressToPointer<SEL *>(SelEntryAddr) = Sel;<br>+    }<br>+  }<br>+}<br>+<br>+Error MachOJITDylibInitializers::registerObjCClasses() const {<br>+  assert(objcRegistrationEnabled() && "ObjC registration not enabled.");<br>+<br>+  struct ObjCClassCompiled {<br>+    void *Metaclass;<br>+    void *Parent;<br>+    void *Cache1;<br>+    void *Cache2;<br>+    void *Data;<br>+  };<br>+<br>+  auto *ImageInfo =<br>+      jitTargetAddressToPointer<const objc_image_info *>(ObjCImageInfoAddr);<br>+  auto ClassSelector = sel_registerName("class");<br>+<br>+  for (const auto &ObjCClassList : ObjCClassListSections) {<br>+    for (uint64_t I = 0; I != ObjCClassList.NumPtrs; ++I) {<br>+      auto ClassPtrAddr = ObjCClassList.Address + (I * sizeof(uintptr_t));<br>+      auto Cls = *jitTargetAddressToPointer<Class *>(ClassPtrAddr);<br>+      auto *ClassCompiled =<br>+          *jitTargetAddressToPointer<ObjCClassCompiled **>(ClassPtrAddr);<br>+      objc_msgSend(reinterpret_cast<id>(ClassCompiled->Parent), ClassSelector);<br>+      auto Registered = objc_readClassPair(Cls, ImageInfo);<br>+<br>+      // FIXME: Improve diagnostic by reporting the failed class's name.<br>+      if (Registered != Cls)<br>+        return make_error<StringError>("Unable to register Objective-C class",<br>+                                       inconvertibleErrorCode());<br>+    }<br>+  }<br>+  return Error::success();<br>+}<br>+<br>+void MachOJITDylibInitializers::dump() const {<br>+  for (auto &Extent : ModInitSections)<br>+    dbgs() << formatv("{0:x16}", Extent.Address) << " -- "<br>+           << formatv("{0:x16}", Extent.Address + 8 * Extent.NumPtrs) << "\n";<br>+}<br>+<br>+MachOPlatform::MachOPlatform(<br>+    ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,<br>+    std::unique_ptr<MemoryBuffer> StandardSymbolsObject)<br>+    : ES(ES), ObjLinkingLayer(ObjLinkingLayer),<br>+      StandardSymbolsObject(std::move(StandardSymbolsObject)) {<br>+  ObjLinkingLayer.addPlugin(std::make_unique<InitScraperPlugin>(*this));<br>+}<br>+<br>+Error MachOPlatform::setupJITDylib(JITDylib &JD) {<br>+  auto ObjBuffer = MemoryBuffer::getMemBuffer(<br>+      StandardSymbolsObject->getMemBufferRef(), false);<br>+  return ObjLinkingLayer.add(JD, std::move(ObjBuffer));<br>+}<br>+<br>+Error MachOPlatform::notifyAdding(JITDylib &JD, const MaterializationUnit &MU) {<br>+  const auto &InitSym = MU.getInitializerSymbol();<br>+  if (!InitSym)<br>+    return Error::success();<br>+<br>+  std::lock_guard<std::mutex> Lock(PlatformMutex);<br>+  RegisteredInitSymbols[&JD].add(InitSym);<br>+  return Error::success();<br>+}<br>+<br>+Error MachOPlatform::notifyRemoving(JITDylib &JD, VModuleKey K) {<br>+  llvm_unreachable("Not supported yet");<br>+}<br>+<br>+Expected<MachOPlatform::InitializerSequence><br>+MachOPlatform::getInitializerSequence(JITDylib &JD) {<br>+<br>+  std::vector<JITDylib *> DFSLinkOrder;<br>+<br>+  while (true) {<br>+    // Lock the platform while we search for any initializer symbols to<br>+    // look up.<br>+    DenseMap<JITDylib *, SymbolLookupSet> NewInitSymbols;<br>+    {<br>+      std::lock_guard<std::mutex> Lock(PlatformMutex);<br>+      DFSLinkOrder = getDFSLinkOrder(JD);<br>+<br>+      for (auto *InitJD : DFSLinkOrder) {<br>+        auto RISItr = RegisteredInitSymbols.find(InitJD);<br>+        if (RISItr != RegisteredInitSymbols.end()) {<br>+          NewInitSymbols[InitJD] = std::move(RISItr->second);<br>+          RegisteredInitSymbols.erase(RISItr);<br>+        }<br>+      }<br>+    }<br>+<br>+    if (NewInitSymbols.empty())<br>+      break;<br>+<br>+    // Outside the lock, issue the lookup.<br>+    if (auto R = lookupInitSymbols(JD.getExecutionSession(), NewInitSymbols))<br>+      ; // Nothing to do in the success case.<br>+    else<br>+      return R.takeError();<br>+  }<br>+<br>+  // Lock again to collect the initializers.<br>+  InitializerSequence FullInitSeq;<br>+  {<br>+    std::lock_guard<std::mutex> Lock(PlatformMutex);<br>+    for (auto *InitJD : reverse(DFSLinkOrder)) {<br>+      auto ISItr = InitSeqs.find(InitJD);<br>+      if (ISItr != InitSeqs.end()) {<br>+        FullInitSeq.emplace_back(InitJD, std::move(ISItr->second));<br>+        InitSeqs.erase(ISItr);<br>+      }<br>+    }<br>+  }<br>+<br>+  return FullInitSeq;<br>+}<br>+<br>+Expected<MachOPlatform::DeinitializerSequence><br>+MachOPlatform::getDeinitializerSequence(JITDylib &JD) {<br>+  std::vector<JITDylib *> DFSLinkOrder = getDFSLinkOrder(JD);<br>+<br>+  DeinitializerSequence FullDeinitSeq;<br>+  {<br>+    std::lock_guard<std::mutex> Lock(PlatformMutex);<br>+    for (auto *DeinitJD : DFSLinkOrder) {<br>+      FullDeinitSeq.emplace_back(DeinitJD, MachOJITDylibDeinitializers());<br>+    }<br>+  }<br>+<br>+  return FullDeinitSeq;<br>+}<br>+<br>+std::vector<JITDylib *> MachOPlatform::getDFSLinkOrder(JITDylib &JD) {<br>+  std::vector<JITDylib *> Result, WorkStack({&JD});<br>+  DenseSet<JITDylib *> Visited;<br>+<br>+  while (!WorkStack.empty()) {<br>+    auto *NextJD = WorkStack.back();<br>+    WorkStack.pop_back();<br>+    if (Visited.count(NextJD))<br>+      continue;<br>+    Visited.insert(NextJD);<br>+    Result.push_back(NextJD);<br>+    NextJD->withSearchOrderDo([&](const JITDylibSearchOrder &SO) {<br>+      for (auto &KV : SO)<br>+        WorkStack.push_back(KV.first);<br>+    });<br>+  }<br>+<br>+  return Result;<br>+}<br>+<br>+void MachOPlatform::registerInitInfo(<br>+    JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,<br>+    MachOJITDylibInitializers::SectionExtent ModInits,<br>+    MachOJITDylibInitializers::SectionExtent ObjCSelRefs,<br>+    MachOJITDylibInitializers::SectionExtent ObjCClassList) {<br>+  std::lock_guard<std::mutex> Lock(PlatformMutex);<br>+<br>+  auto &InitSeq = InitSeqs[&JD];<br>+<br>+  InitSeq.setObjCImageInfoAddr(ObjCImageInfoAddr);<br>+<br>+  if (ModInits.Address)<br>+    InitSeq.addModInitsSection(std::move(ModInits));<br>+<br>+  if (ObjCSelRefs.Address)<br>+    InitSeq.addObjCSelRefsSection(std::move(ObjCSelRefs));<br>+<br>+  if (ObjCClassList.Address)<br>+    InitSeq.addObjCClassListSection(std::move(ObjCClassList));<br>+}<br>+<br>+static Expected<MachOJITDylibInitializers::SectionExtent><br>+getSectionExtent(jitlink::LinkGraph &G, StringRef SectionName) {<br>+  auto *Sec = G.findSectionByName(SectionName);<br>+  if (!Sec)<br>+    return MachOJITDylibInitializers::SectionExtent();<br>+  jitlink::SectionRange R(*Sec);<br>+  if (R.getSize() % G.getPointerSize() != 0)<br>+    return make_error<StringError>(SectionName + " section size is not a "<br>+                                                 "multiple of the pointer size",<br>+                                   inconvertibleErrorCode());<br>+  return MachOJITDylibInitializers::SectionExtent(<br>+      R.getStart(), R.getSize() / G.getPointerSize());<br>+}<br>+<br>+void MachOPlatform::InitScraperPlugin::modifyPassConfig(<br>+    MaterializationResponsibility &MR, const Triple &TT,<br>+    jitlink::PassConfiguration &Config) {<br>+<br>+  Config.PrePrunePasses.push_back([this, &MR](jitlink::LinkGraph &G) -> Error {<br>+    JITLinkSymbolVector InitSectionSymbols;<br>+    preserveInitSectionIfPresent(InitSectionSymbols, G, "__mod_init_func");<br>+    preserveInitSectionIfPresent(InitSectionSymbols, G, "__objc_selrefs");<br>+    preserveInitSectionIfPresent(InitSectionSymbols, G, "__objc_classlist");<br>+<br>+    if (!InitSymbolDeps.empty()) {<br>+      std::lock_guard<std::mutex> Lock(InitScraperMutex);<br>+      InitSymbolDeps[&MR] = std::move(InitSectionSymbols);<br>+    }<br>+<br>+    if (auto Err = processObjCImageInfo(G, MR))<br>+      return Err;<br>+<br>+    return Error::success();<br>+  });<br>+<br>+  Config.PostFixupPasses.push_back([this, &JD = MR.getTargetJITDylib()](<br>+                                       jitlink::LinkGraph &G) -> Error {<br>+    MachOJITDylibInitializers::SectionExtent ModInits, ObjCSelRefs,<br>+        ObjCClassList;<br>+<br>+    JITTargetAddress ObjCImageInfoAddr = 0;<br>+    if (auto *ObjCImageInfoSec = G.findSectionByName("__objc_image_info")) {<br>+      if (auto Addr = jitlink::SectionRange(*ObjCImageInfoSec).getStart()) {<br>+        ObjCImageInfoAddr = Addr;<br>+        dbgs() << "Recorded __objc_imageinfo @ " << formatv("{0:x16}", Addr);<br>+      }<br>+    }<br>+<br>+    // Record __mod_init_func.<br>+    if (auto ModInitsOrErr = getSectionExtent(G, "__mod_init_func"))<br>+      ModInits = std::move(*ModInitsOrErr);<br>+    else<br>+      return ModInitsOrErr.takeError();<br>+<br>+    // Record __objc_selrefs.<br>+    if (auto ObjCSelRefsOrErr = getSectionExtent(G, "__objc_selrefs"))<br>+      ObjCSelRefs = std::move(*ObjCSelRefsOrErr);<br>+    else<br>+      return ObjCSelRefsOrErr.takeError();<br>+<br>+    // Record __objc_classlist.<br>+    if (auto ObjCClassListOrErr = getSectionExtent(G, "__objc_classlist"))<br>+      ObjCClassList = std::move(*ObjCClassListOrErr);<br>+    else<br>+      return ObjCClassListOrErr.takeError();<br>+<br>+    MP.registerInitInfo(JD, ObjCImageInfoAddr, std::move(ModInits),<br>+                        std::move(ObjCSelRefs), std::move(ObjCClassList));<br>+<br>+    return Error::success();<br>+  });<br>+}<br>+<br>+ObjectLinkingLayer::Plugin::LocalDependenciesMap<br>+MachOPlatform::InitScraperPlugin::getSyntheticSymbolLocalDependencies(<br>+    MaterializationResponsibility &MR) {<br>+  std::lock_guard<std::mutex> Lock(InitScraperMutex);<br>+  auto I = InitSymbolDeps.find(&MR);<br>+  if (I != InitSymbolDeps.end()) {<br>+    LocalDependenciesMap Result;<br>+    Result[MR.getInitializerSymbol()] = std::move(I->second);<br>+    InitSymbolDeps.erase(&MR);<br>+    return Result;<br>+  }<br>+  return LocalDependenciesMap();<br>+}<br>+<br>+void MachOPlatform::InitScraperPlugin::preserveInitSectionIfPresent(<br>+    JITLinkSymbolVector &Symbols, jitlink::LinkGraph &G,<br>+    StringRef SectionName) {<br>+  if (auto *Sec = G.findSectionByName(SectionName)) {<br>+    auto SecBlocks = Sec->blocks();<br>+    if (!llvm::empty(SecBlocks))<br>+      Symbols.push_back(<br>+          &G.addAnonymousSymbol(**SecBlocks.begin(), 0, 0, false, true));<br>+  }<br>+}<br>+<br>+Error MachOPlatform::InitScraperPlugin::processObjCImageInfo(<br>+    jitlink::LinkGraph &G, MaterializationResponsibility &MR) {<br>+<br>+  // If there's an ObjC imagine info then either<br>+  //   (1) It's the first __objc_imageinfo we've seen in this JITDylib. In<br>+  //       this case we name and record it.<br>+  // OR<br>+  //   (2) We already have a recorded __objc_imageinfo for this JITDylib,<br>+  //       in which case we just verify it.<br>+  auto *ObjCImageInfo = G.findSectionByName("__objc_imageinfo");<br>+  if (!ObjCImageInfo)<br>+    return Error::success();<br>+<br>+  auto ObjCImageInfoBlocks = ObjCImageInfo->blocks();<br>+<br>+  // Check that the section is not empty if present.<br>+  if (llvm::empty(ObjCImageInfoBlocks))<br>+    return make_error<StringError>("Empty __objc_imageinfo section in " +<br>+                                       G.getName(),<br>+                                   inconvertibleErrorCode());<br>+<br>+  // Check that there's only one block in the section.<br>+  if (std::next(ObjCImageInfoBlocks.begin()) != ObjCImageInfoBlocks.end())<br>+    return make_error<StringError>("Multiple blocks in __objc_imageinfo "<br>+                                   "section in " +<br>+                                       G.getName(),<br>+                                   inconvertibleErrorCode());<br>+<br>+  // Check that the __objc_imageinfo section is unreferenced.<br>+  // FIXME: We could optimize this check if Symbols had a ref-count.<br>+  for (auto &Sec : G.sections()) {<br>+    if (&Sec != ObjCImageInfo)<br>+      for (auto *B : Sec.blocks())<br>+        for (auto &E : B->edges())<br>+          if (E.getTarget().isDefined() &&<br>+              &E.getTarget().getBlock().getSection() == ObjCImageInfo)<br>+            return make_error<StringError>("__objc_imageinfo is referenced "<br>+                                           "within file " +<br>+                                               G.getName(),<br>+                                           inconvertibleErrorCode());<br>+  }<br>+<br>+  auto &ObjCImageInfoBlock = **ObjCImageInfoBlocks.begin();<br>+  auto *ObjCImageInfoData = ObjCImageInfoBlock.getContent().data();<br>+  auto Version = support::endian::read32(ObjCImageInfoData, G.getEndianness());<br>+  auto Flags =<br>+      support::endian::read32(ObjCImageInfoData + 4, G.getEndianness());<br>+<br>+  // Lock the mutex while we verify / update the ObjCImageInfos map.<br>+  std::lock_guard<std::mutex> Lock(InitScraperMutex);<br>+<br>+  auto ObjCImageInfoItr = ObjCImageInfos.find(&MR.getTargetJITDylib());<br>+  if (ObjCImageInfoItr != ObjCImageInfos.end()) {<br>+    // We've already registered an __objc_imageinfo section. Verify the<br>+    // content of this new section matches, then delete it.<br>+    if (ObjCImageInfoItr->second.first != Version)<br>+      return make_error<StringError>(<br>+          "ObjC version in " + G.getName() +<br>+              " does not match first registered version",<br>+          inconvertibleErrorCode());<br>+    if (ObjCImageInfoItr->second.second != Flags)<br>+      return make_error<StringError>("ObjC flags in " + G.getName() +<br>+                                         " do not match first registered flags",<br>+                                     inconvertibleErrorCode());<br>+<br>+    // __objc_imageinfo is valid. Delete the block.<br>+    for (auto *S : ObjCImageInfo->symbols())<br>+      G.removeDefinedSymbol(*S);<br>+    G.removeBlock(ObjCImageInfoBlock);<br>+  } else {<br>+    // We haven't registered an __objc_imageinfo section yet. Register and<br>+    // move on. The section should already be marked no-dead-strip.<br>+    ObjCImageInfos[&MR.getTargetJITDylib()] = std::make_pair(Version, Flags);<br>+  }<br>+<br>+  return Error::success();<br>+}<br>+<br>+} // End namespace orc.<br>+} // End namespace llvm.<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/Mangling.cpp b/llvm/lib/ExecutionEngine/Orc/Mangling.cpp<br>new file mode 100644<br>index 000000000000..7ec7869d00b5<br>--- /dev/null<br>+++ b/llvm/lib/ExecutionEngine/Orc/Mangling.cpp<br>@@ -0,0 +1,131 @@<br>+//===----------- Mangling.cpp -- Name Mangling Utilities for ORC ----------===//<br>+//<br>+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>+// See <a href="https://llvm.org/LICENSE.txt" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#include "llvm/ExecutionEngine/Orc/Mangling.h"<br>+#include "llvm/IR/Constants.h"<br>+#include "llvm/IR/Mangler.h"<br>+#include "llvm/Object/MachO.h"<br>+#include "llvm/Object/ObjectFile.h"<br>+#include "llvm/Support/Debug.h"<br>+<br>+#define DEBUG_TYPE "orc"<br>+<br>+namespace llvm {<br>+namespace orc {<br>+<br>+MangleAndInterner::MangleAndInterner(ExecutionSession &ES, const DataLayout &DL)<br>+    : ES(ES), DL(DL) {}<br>+<br>+SymbolStringPtr MangleAndInterner::operator()(StringRef Name) {<br>+  std::string MangledName;<br>+  {<br>+    raw_string_ostream MangledNameStream(MangledName);<br>+    Mangler::getNameWithPrefix(MangledNameStream, Name, DL);<br>+  }<br>+  return ES.intern(MangledName);<br>+}<br>+<br>+void IRSymbolMapper::add(ExecutionSession &ES, const ManglingOptions &MO,<br>+                         ArrayRef<GlobalValue *> GVs,<br>+                         SymbolFlagsMap &SymbolFlags,<br>+                         SymbolNameToDefinitionMap *SymbolToDefinition) {<br>+  if (GVs.empty())<br>+    return;<br>+<br>+  MangleAndInterner Mangle(ES, GVs[0]->getParent()->getDataLayout());<br>+  for (auto *G : GVs) {<br>+    assert(G && "GVs cannot contain null elements");<br>+    if (!G->hasName() || G->isDeclaration() || G->hasLocalLinkage() ||<br>+        G->hasAvailableExternallyLinkage() || G->hasAppendingLinkage())<br>+      continue;<br>+<br>+    if (G->isThreadLocal() && MO.EmulatedTLS) {<br>+      auto *GV = cast<GlobalVariable>(G);<br>+<br>+      auto Flags = JITSymbolFlags::fromGlobalValue(*GV);<br>+<br>+      auto EmuTLSV = Mangle(("__emutls_v." + GV->getName()).str());<br>+      SymbolFlags[EmuTLSV] = Flags;<br>+      if (SymbolToDefinition)<br>+        (*SymbolToDefinition)[EmuTLSV] = GV;<br>+<br>+      // If this GV has a non-zero initializer we'll need to emit an<br>+      // __emutls.t symbol too.<br>+      if (GV->hasInitializer()) {<br>+        const auto *InitVal = GV->getInitializer();<br>+<br>+        // Skip zero-initializers.<br>+        if (isa<ConstantAggregateZero>(InitVal))<br>+          continue;<br>+        const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal);<br>+        if (InitIntValue && InitIntValue->isZero())<br>+          continue;<br>+<br>+        auto EmuTLST = Mangle(("__emutls_t." + GV->getName()).str());<br>+        SymbolFlags[EmuTLST] = Flags;<br>+        if (SymbolToDefinition)<br>+          (*SymbolToDefinition)[EmuTLST] = GV;<br>+      }<br>+      continue;<br>+    }<br>+<br>+    // Otherwise we just need a normal linker mangling.<br>+    auto MangledName = Mangle(G->getName());<br>+    SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(*G);<br>+    if (SymbolToDefinition)<br>+      (*SymbolToDefinition)[MangledName] = G;<br>+  }<br>+}<br>+<br>+Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>><br>+getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) {<br>+  auto Obj = object::ObjectFile::createObjectFile(ObjBuffer);<br>+<br>+  if (!Obj)<br>+    return Obj.takeError();<br>+<br>+  SymbolFlagsMap SymbolFlags;<br>+  for (auto &Sym : (*Obj)->symbols()) {<br>+    // Skip symbols not defined in this object file.<br>+    if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined)<br>+      continue;<br>+<br>+    // Skip symbols that are not global.<br>+    if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global))<br>+      continue;<br>+<br>+    auto Name = Sym.getName();<br>+    if (!Name)<br>+      return Name.takeError();<br>+    auto InternedName = ES.intern(*Name);<br>+    auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);<br>+    if (!SymFlags)<br>+      return SymFlags.takeError();<br>+    SymbolFlags[InternedName] = std::move(*SymFlags);<br>+  }<br>+<br>+  SymbolStringPtr InitSymbol;<br>+<br>+  if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj->get())) {<br>+    for (auto &Sec : MachOObj->sections()) {<br>+      auto SecType = MachOObj->getSectionType(Sec);<br>+      if ((SecType & MachO::SECTION_TYPE) == MachO::S_MOD_INIT_FUNC_POINTERS) {<br>+        std::string InitSymString;<br>+        raw_string_ostream(InitSymString)<br>+            << "$." << ObjBuffer.getBufferIdentifier() << ".__inits";<br>+        InitSymbol = ES.intern(InitSymString);<br>+        break;<br>+      }<br>+    }<br>+  }<br>+<br>+  return std::make_pair(std::move(SymbolFlags), std::move(InitSymbol));<br>+}<br>+<br>+} // End namespace orc.<br>+} // End namespace llvm.<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp<br>index 6575b0a6ccb2..db88ec8517bf 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp<br>@@ -144,6 +144,10 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {<br>     if (!ExtraSymbolsToClaim.empty())<br>       if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim))<br>         return notifyFailed(std::move(Err));<br>+<br>+    if (const auto &InitSym = MR.getInitializerSymbol())<br>+      InternedResult[InitSym] = JITEvaluatedSymbol();<br>+<br>     if (auto Err = MR.notifyResolved(InternedResult)) {<br>       Layer.getExecutionSession().reportError(std::move(Err));<br>       MR.failMaterialization();<br>@@ -184,8 +188,12 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {<br>   }<br><br> private:<br>-  using JITLinkSymbolSet = DenseSet<const Symbol *>;<br>-  using LocalToNamedDependenciesMap = DenseMap<const Symbol *, JITLinkSymbolSet>;<br>+  struct LocalSymbolNamedDependencies {<br>+    SymbolNameSet Internal, External;<br>+  };<br>+<br>+  using LocalSymbolNamedDependenciesMap =<br>+      DenseMap<const Symbol *, LocalSymbolNamedDependencies>;<br><br>   Error externalizeWeakAndCommonSymbols(LinkGraph &G) {<br>     auto &ES = Layer.getExecutionSession();<br>@@ -216,6 +224,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {<br>     auto &ES = MR.getTargetJITDylib().getExecutionSession();<br>     auto LocalDeps = computeLocalDeps(G);<br><br>+    // Compute dependencies for symbols defined in the JITLink graph.<br>     for (auto *Sym : G.defined_symbols()) {<br><br>       // Skip local symbols: we do not track dependencies for these.<br>@@ -239,15 +248,12 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {<br>           assert(TargetSym.isDefined() &&<br>                  "local symbols must be defined");<br>           auto I = LocalDeps.find(&TargetSym);<br>-          if (I != LocalDeps.end())<br>-            for (auto &S : I->second) {<br>-              assert(S->hasName() &&<br>-                     "LocalDeps should only contain named values");<br>-              if (S->isExternal())<br>-                ExternalSymDeps.insert(ES.intern(S->getName()));<br>-              else if (S != Sym)<br>-                InternalSymDeps.insert(ES.intern(S->getName()));<br>-            }<br>+          if (I != LocalDeps.end()) {<br>+            for (auto &S : I->second.External)<br>+              ExternalSymDeps.insert(S);<br>+            for (auto &S : I->second.Internal)<br>+              InternalSymDeps.insert(S);<br>+          }<br>         }<br>       }<br><br>@@ -261,11 +267,33 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {<br>         InternalNamedSymbolDeps[SymName] = std::move(InternalSymDeps);<br>     }<br><br>+    for (auto &P : Layer.Plugins) {<br>+      auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(MR);<br>+      if (SyntheticLocalDeps.empty())<br>+        continue;<br>+<br>+      for (auto &KV : SyntheticLocalDeps) {<br>+        auto &Name = KV.first;<br>+        auto &LocalDepsForName = KV.second;<br>+        for (auto *Local : LocalDepsForName) {<br>+          assert(Local->getScope() == Scope::Local &&<br>+                 "Dependence on non-local symbol");<br>+          auto LocalNamedDepsItr = LocalDeps.find(Local);<br>+          if (LocalNamedDepsItr == LocalDeps.end())<br>+            continue;<br>+          for (auto &S : LocalNamedDepsItr->second.Internal)<br>+            InternalNamedSymbolDeps[Name].insert(S);<br>+          for (auto &S : LocalNamedDepsItr->second.External)<br>+            ExternalNamedSymbolDeps[Name].insert(S);<br>+        }<br>+      }<br>+    }<br>+<br>     return Error::success();<br>   }<br><br>-  LocalToNamedDependenciesMap computeLocalDeps(LinkGraph &G) {<br>-    LocalToNamedDependenciesMap DepMap;<br>+  LocalSymbolNamedDependenciesMap computeLocalDeps(LinkGraph &G) {<br>+    DenseMap<jitlink::Symbol *, DenseSet<jitlink::Symbol *>> DepMap;<br><br>     // For all local symbols:<br>     // (1) Add their named dependencies.<br>@@ -319,7 +347,26 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {<br>       }<br>     } while (Changed);<br><br>-    return DepMap;<br>+    // Intern the results to produce a mapping of jitlink::Symbol* to internal<br>+    // and external symbol names.<br>+    auto &ES = Layer.getExecutionSession();<br>+    LocalSymbolNamedDependenciesMap Result;<br>+    for (auto &KV : DepMap) {<br>+      auto *Local = KV.first;<br>+      assert(Local->getScope() == Scope::Local &&<br>+             "DepMap keys should all be local symbols");<br>+      auto &LocalNamedDeps = Result[Local];<br>+      for (auto *Named : KV.second) {<br>+        assert(Named->getScope() != Scope::Local &&<br>+               "DepMap values should all be non-local symbol sets");<br>+        if (Named->isExternal())<br>+          LocalNamedDeps.External.insert(ES.intern(Named->getName()));<br>+        else<br>+          LocalNamedDeps.Internal.insert(ES.intern(Named->getName()));<br>+      }<br>+    }<br>+<br>+    return Result;<br>   }<br><br>   void registerDependencies(const SymbolDependenceMap &QueryDeps) {<br><br>diff  --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp<br>index ff8289a264c8..0eaf13c6e3c8 100644<br>--- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp<br>+++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp<br>@@ -88,7 +88,8 @@ RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() {<br> void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,<br>                                     std::unique_ptr<MemoryBuffer> O) {<br>   assert(O && "Object must not be null");<br>-<br>+  dbgs() << "Emitting via RTDyldObjectLinkingLayer:\n"<br>+         << R.getSymbols() << "\n";<br>   // This method launches an asynchronous link step that will fulfill our<br>   // materialization responsibility. We need to switch R to be heap<br>   // allocated before that happens so it can live as long as the asynchronous<br>@@ -229,6 +230,9 @@ Error RTDyldObjectLinkingLayer::onObjLoad(<br>         Symbols.erase(KV.first);<br>   }<br><br>+  if (const auto &InitSym = R.getInitializerSymbol())<br>+    Symbols[InitSym] = JITEvaluatedSymbol();<br>+<br>   if (auto Err = R.notifyResolved(Symbols)) {<br>     R.failMaterialization();<br>     return Err;<br><br>diff  --git a/llvm/test/ExecutionEngine/OrcLazy/objc-minimal.ll b/llvm/test/ExecutionEngine/OrcLazy/objc-minimal.ll<br>new file mode 100644<br>index 000000000000..8a940573dcb9<br>--- /dev/null<br>+++ b/llvm/test/ExecutionEngine/OrcLazy/objc-minimal.ll<br>@@ -0,0 +1,73 @@<br>+; REQUIRES: system-darwin<br>+; RUN: lli -jit-kind=orc-lazy %s<br>+;<br>+; Sanity check MachO Platform support: Call a no-op method (returning int 0) on<br>+; an ObjC object. This test checks that we correctly auto-identify this as a<br>+; MachO target, configure MachOPlatform support, and correctly register the<br>+; class metadata and method selector with the Objective-C runtime.<br>+<br>+source_filename = "<a href="http://objc-minimal.mm" target="_blank">objc-minimal.mm</a>"<br>+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>+target triple = "x86_64-apple-macosx10.14.0"<br>+<br>+%0 = type opaque<br>+%struct._objc_cache = type opaque<br>+%struct._class_t = type { %struct._class_t*, %struct._class_t*, %struct._objc_cache*, i8* (i8*, i8*)**, %struct._class_ro_t* }<br>+%struct._class_ro_t = type { i32, i32, i32, i8*, i8*, %struct.__method_list_t*, %struct._objc_protocol_list*, %struct._ivar_list_t*, i8*, %struct._prop_list_t* }<br>+%struct.__method_list_t = type { i32, i32, [0 x %struct._objc_method] }<br>+%struct._objc_method = type { i8*, i8*, i8* }<br>+%struct._objc_protocol_list = type { i64, [0 x %struct._protocol_t*] }<br>+%struct._protocol_t = type { i8*, i8*, %struct._objc_protocol_list*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct._prop_list_t*, i32, i32, i8**, i8*, %struct._prop_list_t* }<br>+%struct._ivar_list_t = type { i32, i32, [0 x %struct._ivar_t] }<br>+%struct._ivar_t = type { i64*, i8*, i8*, i32, i32 }<br>+%struct._prop_list_t = type { i32, i32, [0 x %struct._prop_t] }<br>+%struct._prop_t = type { i8*, i8* }<br>+<br>+@_objc_empty_cache = external global %struct._objc_cache<br>+@"OBJC_METACLASS_$_NSObject" = external global %struct._class_t<br>+@OBJC_CLASS_NAME_ = private unnamed_addr constant [4 x i8] c"Foo\00", section "__TEXT,__objc_classname,cstring_literals", align 1<br>+@"\01l_OBJC_METACLASS_RO_$_Foo" = private global %struct._class_ro_t { i32 1, i32 40, i32 40, i8* null, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), %struct.__method_list_t* null, %struct._objc_protocol_list* null, %struct._ivar_list_t* null, i8* null, %struct._prop_list_t* null }, section "__DATA, __objc_const", align 8<br>+@"OBJC_METACLASS_$_Foo" = global %struct._class_t { %struct._class_t* @"OBJC_METACLASS_$_NSObject", %struct._class_t* @"OBJC_METACLASS_$_NSObject", %struct._objc_cache* @_objc_empty_cache, i8* (i8*, i8*)** null, %struct._class_ro_t* @"\01l_OBJC_METACLASS_RO_$_Foo" }, section "__DATA, __objc_data", align 8<br>+@"OBJC_CLASS_$_NSObject" = external global %struct._class_t<br>+@OBJC_METH_VAR_NAME_ = private unnamed_addr constant [4 x i8] c"foo\00", section "__TEXT,__objc_methname,cstring_literals", align 1<br>+@OBJC_METH_VAR_TYPE_ = private unnamed_addr constant [8 x i8] c"i16@0:8\00", section "__TEXT,__objc_methtype,cstring_literals", align 1<br>+@"\01l_OBJC_$_INSTANCE_METHODS_Foo" = private global { i32, i32, [1 x %struct._objc_method] } { i32 24, i32 1, [1 x %struct._objc_method] [%struct._objc_method { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @OBJC_METH_VAR_NAME_, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @OBJC_METH_VAR_TYPE_, i32 0, i32 0), i8* bitcast (i32 (%0*, i8*)* @"\01-[Foo foo]" to i8*) }] }, section "__DATA, __objc_const", align 8<br>+@"\01l_OBJC_CLASS_RO_$_Foo" = private global %struct._class_ro_t { i32 0, i32 8, i32 8, i8* null, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), %struct.__method_list_t* bitcast ({ i32, i32, [1 x %struct._objc_method] }* @"\01l_OBJC_$_INSTANCE_METHODS_Foo" to %struct.__method_list_t*), %struct._objc_protocol_list* null, %struct._ivar_list_t* null, i8* null, %struct._prop_list_t* null }, section "__DATA, __objc_const", align 8<br>+@"OBJC_CLASS_$_Foo" = global %struct._class_t { %struct._class_t* @"OBJC_METACLASS_$_Foo", %struct._class_t* @"OBJC_CLASS_$_NSObject", %struct._objc_cache* @_objc_empty_cache, i8* (i8*, i8*)** null, %struct._class_ro_t* @"\01l_OBJC_CLASS_RO_$_Foo" }, section "__DATA, __objc_data", align 8<br>+@"OBJC_CLASSLIST_REFERENCES_$_" = private global %struct._class_t* @"OBJC_CLASS_$_Foo", section "__DATA,__objc_classrefs,regular,no_dead_strip", align 8<br>+@OBJC_METH_VAR_NAME_.1 = private unnamed_addr constant [5 x i8] c"init\00", section "__TEXT,__objc_methname,cstring_literals", align 1<br>+@OBJC_SELECTOR_REFERENCES_ = private externally_initialized global i8* getelementptr inbounds ([5 x i8], [5 x i8]* @OBJC_METH_VAR_NAME_.1, i64 0, i64 0), section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8<br>+@OBJC_SELECTOR_REFERENCES_.2 = private externally_initialized global i8* getelementptr inbounds ([4 x i8], [4 x i8]* @OBJC_METH_VAR_NAME_, i64 0, i64 0), section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8<br>+@"OBJC_LABEL_CLASS_$" = private global [1 x i8*] [i8* bitcast (%struct._class_t* @"OBJC_CLASS_$_Foo" to i8*)], section "__DATA,__objc_classlist,regular,no_dead_strip", align 8<br>+@llvm.compiler.used = appending global [9 x i8*] [i8* bitcast ({ i32, i32, [1 x %struct._objc_method] }* @"\01l_OBJC_$_INSTANCE_METHODS_Foo" to i8*), i8* bitcast (%struct._class_t** @"OBJC_CLASSLIST_REFERENCES_$_" to i8*), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @OBJC_CLASS_NAME_, i32 0, i32 0), i8* bitcast ([1 x i8*]* @"OBJC_LABEL_CLASS_$" to i8*), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @OBJC_METH_VAR_NAME_, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @OBJC_METH_VAR_NAME_.1, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @OBJC_METH_VAR_TYPE_, i32 0, i32 0), i8* bitcast (i8** @OBJC_SELECTOR_REFERENCES_ to i8*), i8* bitcast (i8** @OBJC_SELECTOR_REFERENCES_.2 to i8*)], section "llvm.metadata"<br>+<br>+; Function Attrs: noinline norecurse nounwind readnone ssp uwtable<br>+define internal i32 @"\01-[Foo foo]"(%0* nocapture readnone, i8* nocapture readnone) {<br>+  ret i32 0<br>+}<br>+<br>+; Function Attrs: noinline norecurse ssp uwtable<br>+define i32 @main(i32, i8** nocapture readnone) local_unnamed_addr {<br>+  %3 = load i8*, i8** bitcast (%struct._class_t** @"OBJC_CLASSLIST_REFERENCES_$_" to i8**), align 8<br>+  %4 = tail call i8* @objc_alloc(i8* %3)<br>+  %5 = load i8*, i8** @OBJC_SELECTOR_REFERENCES_, align 8<br>+  %6 = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %4, i8* %5)<br>+  %7 = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.2, align 8<br>+  %8 = tail call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*)(i8* %6, i8* %7)<br>+  ret i32 %8<br>+}<br>+<br>+declare i8* @objc_alloc(i8*) local_unnamed_addr<br>+<br>+; Function Attrs: nonlazybind<br>+declare i8* @objc_msgSend(i8*, i8*, ...) local_unnamed_addr<br>+<br>+!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6 }<br>+<br>+!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 15]}<br>+!1 = !{i32 1, !"Objective-C Version", i32 2}<br>+!2 = !{i32 1, !"Objective-C Image Info Version", i32 0}<br>+!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}<br>+!4 = !{i32 4, !"Objective-C Garbage Collection", i32 0}<br>+!5 = !{i32 1, !"Objective-C Class Properties", i32 64}<br>+!6 = !{i32 1, !"wchar_size", i32 4}<br><br>diff  --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp<br>index e7251b12f7fc..55b9557bddfe 100644<br>--- a/llvm/tools/lli/lli.cpp<br>+++ b/llvm/tools/lli/lli.cpp<br>@@ -24,9 +24,11 @@<br> #include "llvm/ExecutionEngine/JITEventListener.h"<br> #include "llvm/ExecutionEngine/MCJIT.h"<br> #include "llvm/ExecutionEngine/ObjectCache.h"<br>+#include "llvm/ExecutionEngine/Orc/DebugUtils.h"<br> #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"<br> #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"<br> #include "llvm/ExecutionEngine/Orc/LLJIT.h"<br>+#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"<br> #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"<br> #include "llvm/ExecutionEngine/OrcMCJITReplacement.h"<br> #include "llvm/ExecutionEngine/SectionMemoryManager.h"<br>@@ -206,6 +208,19 @@ namespace {<br>       cl::desc("Do not resolve lli process symbols in JIT'd code"),<br>       cl::init(false));<br><br>+  enum class LLJITPlatform { DetectHost, GenericIR, MachO };<br>+<br>+  cl::opt<LLJITPlatform><br>+      Platform("lljit-platform", cl::desc("Platform to use with LLJIT"),<br>+               cl::init(LLJITPlatform::DetectHost),<br>+               cl::values(clEnumValN(LLJITPlatform::DetectHost, "DetectHost",<br>+                                     "Select based on JIT target triple"),<br>+                          clEnumValN(LLJITPlatform::GenericIR, "GenericIR",<br>+                                     "Use LLJITGenericIRPlatform"),<br>+                          clEnumValN(LLJITPlatform::MachO, "MachO",<br>+                                     "Use LLJITMachOPlatform")),<br>+               cl::Hidden);<br>+<br>   enum class DumpKind {<br>     NoDump,<br>     DumpFuncsToStdOut,<br>@@ -772,16 +787,20 @@ int runOrcLazyJIT(const char *ProgName) {<br>   if (!MainModule)<br>     reportError(Err, ProgName);<br><br>-  const auto &TT = MainModule->getTargetTriple();<br>+  Triple TT(MainModule->getTargetTriple());<br>   orc::LLLazyJITBuilder Builder;<br><br>   Builder.setJITTargetMachineBuilder(<br>-      TT.empty() ? ExitOnErr(orc::JITTargetMachineBuilder::detectHost())<br>-                 : orc::JITTargetMachineBuilder(Triple(TT)));<br>+      MainModule->getTargetTriple().empty()<br>+          ? ExitOnErr(orc::JITTargetMachineBuilder::detectHost())<br>+          : orc::JITTargetMachineBuilder(TT));<br><br>   if (!MArch.empty())<br>     Builder.getJITTargetMachineBuilder()->getTargetTriple().setArchName(MArch);<br><br>+  if (!MainModule->getDataLayout().isDefault())<br>+    Builder.setDataLayout(MainModule->getDataLayout());<br>+<br>   Builder.getJITTargetMachineBuilder()<br>       ->setCPU(getCPUStr())<br>       .addFeatures(getFeatureList())<br>@@ -796,6 +815,29 @@ int runOrcLazyJIT(const char *ProgName) {<br>       pointerToJITTargetAddress(exitOnLazyCallThroughFailure));<br>   Builder.setNumCompileThreads(LazyJITCompileThreads);<br><br>+  // Set up LLJIT platform.<br>+  {<br>+    LLJITPlatform P = Platform;<br>+    if (P == LLJITPlatform::DetectHost) {<br>+      if (TT.isOSBinFormatMachO())<br>+        P = LLJITPlatform::MachO;<br>+      else<br>+        P = LLJITPlatform::GenericIR;<br>+    }<br>+<br>+    switch (P) {<br>+    case LLJITPlatform::GenericIR:<br>+      // Nothing to do: LLJITBuilder will use this by default.<br>+      break;<br>+    case LLJITPlatform::MachO:<br>+      Builder.setPlatformSetUp(orc::setUpMachOPlatform);<br>+      ExitOnErr(orc::enableObjCRegistration("libobjc.dylib"));<br>+      break;<br>+    default:<br>+      llvm_unreachable("Unrecognized platform value");<br>+    }<br>+  }<br>+<br>   auto J = ExitOnErr(Builder.create());<br><br>   if (PerModuleLazy)<br>@@ -828,9 +870,6 @@ int runOrcLazyJIT(const char *ProgName) {<br>               return Name != MainName;<br>             })));<br><br>-  orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;<br>-  ExitOnErr(CXXRuntimeOverrides.enable(J->getMainJITDylib(), Mangle));<br>-<br>   // Add the main module.<br>   ExitOnErr(<br>       J->addLazyIRModule(orc::ThreadSafeModule(std::move(MainModule), TSCtx)));<br>@@ -845,8 +884,11 @@ int runOrcLazyJIT(const char *ProgName) {<br>     for (auto JDItr = JITDylibs.begin(), JDEnd = JITDylibs.end();<br>          JDItr != JDEnd; ++JDItr) {<br>       orc::JITDylib *JD = J->getJITDylibByName(*JDItr);<br>-      if (!JD)<br>-        JD = &J->createJITDylib(*JDItr);<br>+      if (!JD) {<br>+        JD = &ExitOnErr(J->createJITDylib(*JDItr));<br>+        J->getMainJITDylib().addToSearchOrder(*JD);<br>+        JD->addToSearchOrder(J->getMainJITDylib());<br>+      }<br>       IdxToDylib[JITDylibs.getPosition(JDItr - JITDylibs.begin())] = JD;<br>     }<br><br>@@ -882,7 +924,7 @@ int runOrcLazyJIT(const char *ProgName) {<br>   }<br><br>   // Run any static constructors.<br>-  ExitOnErr(J->runConstructors());<br>+  ExitOnErr(J->initialize(J->getMainJITDylib()));<br><br>   // Run any -thread-entry points.<br>   std::vector<std::thread> AltEntryThreads;<br>@@ -907,8 +949,7 @@ int runOrcLazyJIT(const char *ProgName) {<br>     AltEntryThread.join();<br><br>   // Run destructors.<br>-  ExitOnErr(J->runDestructors());<br>-  CXXRuntimeOverrides.runDestructors();<br>+  ExitOnErr(J->deinitialize(J->getMainJITDylib()));<br><br>   return Result;<br> }<br><br>diff  --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp<br>index 26bcf46d60a6..7765d53f402d 100644<br>--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp<br>+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp<br>@@ -396,9 +396,18 @@ static std::unique_ptr<jitlink::JITLinkMemoryManager> createMemoryManager() {<br>   return std::make_unique<jitlink::InProcessMemoryManager>();<br> }<br><br>-Session::Session(Triple TT)<br>-    : MainJD(ES.createJITDylib("<main>")), ObjLayer(ES, createMemoryManager()),<br>-      TT(std::move(TT)) {<br>+Expected<std::unique_ptr<Session>> Session::Create(Triple TT) {<br>+  Error Err = Error::success();<br>+  std::unique_ptr<Session> S(new Session(std::move(TT), Err));<br>+  if (Err)<br>+    return std::move(Err);<br>+  return std::move(S);<br>+}<br>+<br>+// FIXME: Move to createJITDylib if/when we start using Platform support in<br>+// llvm-jitlink.<br>+Session::Session(Triple TT, Error &Err)<br>+    : ObjLayer(ES, createMemoryManager()), TT(std::move(TT)) {<br><br>   /// Local ObjectLinkingLayer::Plugin class to forward modifyPassConfig to the<br>   /// Session.<br>@@ -414,6 +423,15 @@ Session::Session(Triple TT)<br>     Session &S;<br>   };<br><br>+  ErrorAsOutParameter _(&Err);<br>+<br>+  if (auto MainJDOrErr = ES.createJITDylib("main"))<br>+    MainJD = &*MainJDOrErr;<br>+  else {<br>+    Err = MainJDOrErr.takeError();<br>+    return;<br>+  }<br>+<br>   if (!NoExec && !TT.isOSWindows())<br>     ObjLayer.addPlugin(std::make_unique<EHFrameRegistrationPlugin>(<br>         InProcessEHFrameRegistrar::getInstance()));<br>@@ -561,7 +579,7 @@ Error loadProcessSymbols(Session &S) {<br>   auto FilterMainEntryPoint = [InternedEntryPointName](SymbolStringPtr Name) {<br>     return Name != InternedEntryPointName;<br>   };<br>-  S.MainJD.addGenerator(<br>+  S.MainJD->addGenerator(<br>       ExitOnErr(orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(<br>           GlobalPrefix, FilterMainEntryPoint)));<br><br>@@ -590,20 +608,22 @@ Error loadObjects(Session &S) {<br>   LLVM_DEBUG(dbgs() << "Creating JITDylibs...\n");<br>   {<br>     // Create a "main" JITLinkDylib.<br>-    IdxToJLD[0] = &S.MainJD;<br>-    S.JDSearchOrder.push_back(&S.MainJD);<br>-    LLVM_DEBUG(dbgs() << "  0: " << S.MainJD.getName() << "\n");<br>+    IdxToJLD[0] = S.MainJD;<br>+    S.JDSearchOrder.push_back(S.MainJD);<br>+    LLVM_DEBUG(dbgs() << "  0: " << S.MainJD->getName() << "\n");<br><br>     // Add any extra JITLinkDylibs from the command line.<br>     std::string JDNamePrefix("lib");<br>     for (auto JLDItr = JITLinkDylibs.begin(), JLDEnd = JITLinkDylibs.end();<br>          JLDItr != JLDEnd; ++JLDItr) {<br>-      auto &JD = S.ES.createJITDylib(JDNamePrefix + *JLDItr);<br>+      auto JD = S.ES.createJITDylib(JDNamePrefix + *JLDItr);<br>+      if (!JD)<br>+        return JD.takeError();<br>       unsigned JDIdx =<br>           JITLinkDylibs.getPosition(JLDItr - JITLinkDylibs.begin());<br>-      IdxToJLD[JDIdx] = &JD;<br>-      S.JDSearchOrder.push_back(&JD);<br>-      LLVM_DEBUG(dbgs() << "  " << JDIdx << ": " << JD.getName() << "\n");<br>+      IdxToJLD[JDIdx] = &*JD;<br>+      S.JDSearchOrder.push_back(&*JD);<br>+      LLVM_DEBUG(dbgs() << "  " << JDIdx << ": " << JD->getName() << "\n");<br>     }<br><br>     // Set every dylib to link against every other, in command line order.<br>@@ -790,32 +810,32 @@ int main(int argc, char *argv[]) {<br>   std::unique_ptr<JITLinkTimers> Timers =<br>       ShowTimes ? std::make_unique<JITLinkTimers>() : nullptr;<br><br>-  Session S(getFirstFileTriple());<br>+  auto S = ExitOnErr(Session::Create(getFirstFileTriple()));<br><br>-  ExitOnErr(sanitizeArguments(S));<br>+  ExitOnErr(sanitizeArguments(*S));<br><br>   if (!NoProcessSymbols)<br>-    ExitOnErr(loadProcessSymbols(S));<br>+    ExitOnErr(loadProcessSymbols(*S));<br>   ExitOnErr(loadDylibs());<br><br><br>   {<br>     TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);<br>-    ExitOnErr(loadObjects(S));<br>+    ExitOnErr(loadObjects(*S));<br>   }<br><br>   JITEvaluatedSymbol EntryPoint = 0;<br>   {<br>     TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr);<br>-    EntryPoint = ExitOnErr(getMainEntryPoint(S));<br>+    EntryPoint = ExitOnErr(getMainEntryPoint(*S));<br>   }<br><br>   if (ShowAddrs)<br>-    S.dumpSessionInfo(outs());<br>+    S->dumpSessionInfo(outs());<br><br>-  ExitOnErr(runChecks(S));<br>+  ExitOnErr(runChecks(*S));<br><br>-  dumpSessionStats(S);<br>+  dumpSessionStats(*S);<br><br>   if (NoExec)<br>     return 0;<br><br>diff  --git a/llvm/tools/llvm-jitlink/llvm-jitlink.h b/llvm/tools/llvm-jitlink/llvm-jitlink.h<br>index 0f92d7605012..c888baec9adf 100644<br>--- a/llvm/tools/llvm-jitlink/llvm-jitlink.h<br>+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.h<br>@@ -26,12 +26,13 @@ namespace llvm {<br><br> struct Session {<br>   orc::ExecutionSession ES;<br>-  orc::JITDylib &MainJD;<br>+  orc::JITDylib *MainJD;<br>   orc::ObjectLinkingLayer ObjLayer;<br>   std::vector<orc::JITDylib *> JDSearchOrder;<br>   Triple TT;<br><br>   Session(Triple TT);<br>+  static Expected<std::unique_ptr<Session>> Create(Triple TT);<br>   void dumpSessionInfo(raw_ostream &OS);<br>   void modifyPassConfig(const Triple &FTT,<br>                         jitlink::PassConfiguration &PassConfig);<br>@@ -63,6 +64,9 @@ struct Session {<br>   FileInfoMap FileInfos;<br>   uint64_t SizeBeforePruning = 0;<br>   uint64_t SizeAfterFixups = 0;<br>+<br>+private:<br>+  Session(Triple TT, Error &Err);<br> };<br><br> Error registerMachOStubsAndGOT(Session &S, jitlink::LinkGraph &G);<br><br>diff  --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp<br>index 68a6d2ed2ca2..171ff37f0069 100644<br>--- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp<br>+++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp<br>@@ -113,6 +113,7 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {<br>         cantFail(R.notifyResolved({{Bar, BarSym}}));<br>         cantFail(R.notifyEmitted());<br>       },<br>+      nullptr,<br>       [&](const JITDylib &JD, const SymbolStringPtr &Name) {<br>         EXPECT_EQ(Name, Bar) << "Expected \"Bar\" to be discarded";<br>         if (Name == Bar)<br>@@ -126,6 +127,7 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {<br>   cantFail(JD.define(std::make_unique<SimpleMaterializationUnit>(<br>       SymbolFlagsMap({{Baz, BazSym.getFlags()}}),<br>       [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); },<br>+      nullptr,<br>       [](const JITDylib &JD, const SymbolStringPtr &Name) {<br>         ADD_FAILURE() << "\"Baz\" discarded unexpectedly";<br>       })));<br>@@ -176,7 +178,7 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {<br> TEST_F(CoreAPIsStandardTest, ChainedJITDylibLookup) {<br>   cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));<br><br>-  auto &JD2 = ES.createJITDylib("JD2");<br>+  auto &JD2 = ES.createBareJITDylib("JD2");<br><br>   bool OnCompletionRun = false;<br><br>@@ -198,7 +200,7 @@ TEST_F(CoreAPIsStandardTest, LookupWithHiddenSymbols) {<br><br>   cantFail(JD.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarHiddenSym}})));<br><br>-  auto &JD2 = ES.createJITDylib("JD2");<br>+  auto &JD2 = ES.createBareJITDylib("JD2");<br>   cantFail(JD2.define(absoluteSymbols({{Bar, QuxSym}})));<br><br>   /// Try a blocking lookup.<br>@@ -307,7 +309,7 @@ TEST_F(CoreAPIsStandardTest, TestBasicReExports) {<br>   // JITDylib works.<br>   cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));<br><br>-  auto &JD2 = ES.createJITDylib("JD2");<br>+  auto &JD2 = ES.createBareJITDylib("JD2");<br><br>   cantFail(JD2.define(reexports(JD, {{Bar, {Foo, BarSym.getFlags()}}})));<br><br>@@ -332,7 +334,7 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) {<br><br>   cantFail(JD.define(BarMU));<br><br>-  auto &JD2 = ES.createJITDylib("JD2");<br>+  auto &JD2 = ES.createBareJITDylib("JD2");<br><br>   cantFail(JD2.define(reexports(<br>       JD, {{Baz, {Foo, BazSym.getFlags()}}, {Qux, {Bar, QuxSym.getFlags()}}})));<br>@@ -347,7 +349,7 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) {<br> TEST_F(CoreAPIsStandardTest, TestReexportsGenerator) {<br>   // Test that a re-exports generator can dynamically generate reexports.<br><br>-  auto &JD2 = ES.createJITDylib("JD2");<br>+  auto &JD2 = ES.createBareJITDylib("JD2");<br>   cantFail(JD2.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));<br><br>   auto Filter = [this](SymbolStringPtr Name) { return Name != Bar; };<br>@@ -838,6 +840,7 @@ TEST_F(CoreAPIsStandardTest, DropMaterializerWhenEmpty) {<br>       [](MaterializationResponsibility R) {<br>         llvm_unreachable("Unexpected call to materialize");<br>       },<br>+      nullptr,<br>       [&](const JITDylib &JD, SymbolStringPtr Name) {<br>         EXPECT_TRUE(Name == Foo || Name == Bar)<br>             << "Discard of unexpected symbol?";<br>@@ -872,6 +875,7 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) {<br>         cantFail(R.notifyEmitted());<br>         FooMaterialized = true;<br>       },<br>+      nullptr,<br>       [&](const JITDylib &JD, SymbolStringPtr Name) {<br>         EXPECT_EQ(Name, Bar) << "Expected Name to be Bar";<br>         BarDiscarded = true;<br>@@ -920,6 +924,7 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {<br>         ADD_FAILURE() << "Attempt to materialize Bar from the wrong unit";<br>         R.failMaterialization();<br>       },<br>+      nullptr,<br>       [&](const JITDylib &JD, SymbolStringPtr Name) {<br>         EXPECT_EQ(Name, Bar) << "Expected \"Bar\" to be discarded";<br>         DuplicateBarDiscarded = true;<br><br>diff  --git a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h<br>index d82012b5a853..b25851d8f796 100644<br>--- a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h<br>+++ b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h<br>@@ -47,7 +47,7 @@ class CoreAPIsBasedStandardTest : public testing::Test {<br> protected:<br>   std::shared_ptr<SymbolStringPool> SSP = std::make_shared<SymbolStringPool>();<br>   ExecutionSession ES{SSP};<br>-  JITDylib &JD = ES.createJITDylib("JD");<br>+  JITDylib &JD = ES.createBareJITDylib("JD");<br>   SymbolStringPtr Foo = ES.intern("foo");<br>   SymbolStringPtr Bar = ES.intern("bar");<br>   SymbolStringPtr Baz = ES.intern("baz");<br>@@ -93,9 +93,11 @@ class SimpleMaterializationUnit : public orc::MaterializationUnit {<br><br>   SimpleMaterializationUnit(<br>       orc::SymbolFlagsMap SymbolFlags, MaterializeFunction Materialize,<br>+      orc::SymbolStringPtr InitSym = nullptr,<br>       DiscardFunction Discard = DiscardFunction(),<br>       DestructorFunction Destructor = DestructorFunction())<br>-      : MaterializationUnit(std::move(SymbolFlags), orc::VModuleKey()),<br>+      : MaterializationUnit(std::move(SymbolFlags), std::move(InitSym),<br>+                            orc::VModuleKey()),<br>         Materialize(std::move(Materialize)), Discard(std::move(Discard)),<br>         Destructor(std::move(Destructor)) {}<br><br><br>diff  --git a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp<br>index 0c66841e9af0..9a50571b1969 100644<br>--- a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp<br>+++ b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp<br>@@ -50,7 +50,7 @@ static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj,<br>   bool DebugSectionSeen = false;<br><br>   ExecutionSession ES;<br>-  auto &JD = ES.createJITDylib("main");<br>+  auto &JD = ES.createBareJITDylib("main");<br>   auto Foo = ES.intern("foo");<br><br>   RTDyldObjectLinkingLayer ObjLayer(ES, [&DebugSectionSeen]() {<br>@@ -151,7 +151,7 @@ TEST(RTDyldObjectLinkingLayerTest, TestOverrideObjectFlags) {<br><br>   // Create a simple stack and set the override flags option.<br>   ExecutionSession ES;<br>-  auto &JD = ES.createJITDylib("main");<br>+  auto &JD = ES.createBareJITDylib("main");<br>   auto Foo = ES.intern("foo");<br>   RTDyldObjectLinkingLayer ObjLayer(<br>       ES, []() { return std::make_unique<SectionMemoryManager>(); });<br>@@ -218,7 +218,7 @@ TEST(RTDyldObjectLinkingLayerTest, TestAutoClaimResponsibilityForSymbols) {<br><br>   // Create a simple stack and set the override flags option.<br>   ExecutionSession ES;<br>-  auto &JD = ES.createJITDylib("main");<br>+  auto &JD = ES.createBareJITDylib("main");<br>   auto Foo = ES.intern("foo");<br>   RTDyldObjectLinkingLayer ObjLayer(<br>       ES, []() { return std::make_unique<SectionMemoryManager>(); });<br><br><br><br>_______________________________________________<br>llvm-commits mailing list<br><a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br><a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br></div></div></blockquote></div><br></div></div></blockquote></div></div></blockquote></div></div>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>