Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- MachOPlatform.h - Utilities for executing MachO in Orc --*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Utilities for executing JIT'd MachO in Orc.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
  14. #define LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
  15.  
  16. #include "llvm/ADT/StringRef.h"
  17. #include "llvm/ExecutionEngine/Orc/Core.h"
  18. #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
  19. #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
  20. #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
  21.  
  22. #include <future>
  23. #include <thread>
  24. #include <vector>
  25.  
  26. namespace llvm {
  27. namespace orc {
  28.  
  29. /// Mediates between MachO initialization and ExecutionSession state.
  30. class MachOPlatform : public Platform {
  31. public:
  32.   // Used internally by MachOPlatform, but made public to enable serialization.
  33.   struct MachOJITDylibDepInfo {
  34.     bool Sealed = false;
  35.     std::vector<ExecutorAddr> DepHeaders;
  36.   };
  37.  
  38.   // Used internally by MachOPlatform, but made public to enable serialization.
  39.   using MachOJITDylibDepInfoMap =
  40.       std::vector<std::pair<ExecutorAddr, MachOJITDylibDepInfo>>;
  41.  
  42.   /// Try to create a MachOPlatform instance, adding the ORC runtime to the
  43.   /// given JITDylib.
  44.   ///
  45.   /// The ORC runtime requires access to a number of symbols in libc++, and
  46.   /// requires access to symbols in libobjc, and libswiftCore to support
  47.   /// Objective-C and Swift code. It is up to the caller to ensure that the
  48.   /// requried symbols can be referenced by code added to PlatformJD. The
  49.   /// standard way to achieve this is to first attach dynamic library search
  50.   /// generators for either the given process, or for the specific required
  51.   /// libraries, to PlatformJD, then to create the platform instance:
  52.   ///
  53.   /// \code{.cpp}
  54.   ///   auto &PlatformJD = ES.createBareJITDylib("stdlib");
  55.   ///   PlatformJD.addGenerator(
  56.   ///     ExitOnErr(EPCDynamicLibrarySearchGenerator
  57.   ///                 ::GetForTargetProcess(EPC)));
  58.   ///   ES.setPlatform(
  59.   ///     ExitOnErr(MachOPlatform::Create(ES, ObjLayer, EPC, PlatformJD,
  60.   ///                                     "/path/to/orc/runtime")));
  61.   /// \endcode
  62.   ///
  63.   /// Alternatively, these symbols could be added to another JITDylib that
  64.   /// PlatformJD links against.
  65.   ///
  66.   /// Clients are also responsible for ensuring that any JIT'd code that
  67.   /// depends on runtime functions (including any code using TLV or static
  68.   /// destructors) can reference the runtime symbols. This is usually achieved
  69.   /// by linking any JITDylibs containing regular code against
  70.   /// PlatformJD.
  71.   ///
  72.   /// By default, MachOPlatform will add the set of aliases returned by the
  73.   /// standardPlatformAliases function. This includes both required aliases
  74.   /// (e.g. __cxa_atexit -> __orc_rt_macho_cxa_atexit for static destructor
  75.   /// support), and optional aliases that provide JIT versions of common
  76.   /// functions (e.g. dlopen -> __orc_rt_macho_jit_dlopen). Clients can
  77.   /// override these defaults by passing a non-None value for the
  78.   /// RuntimeAliases function, in which case the client is responsible for
  79.   /// setting up all aliases (including the required ones).
  80.   static Expected<std::unique_ptr<MachOPlatform>>
  81.   Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
  82.          JITDylib &PlatformJD, const char *OrcRuntimePath,
  83.          std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
  84.  
  85.   ExecutionSession &getExecutionSession() const { return ES; }
  86.   ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
  87.  
  88.   Error setupJITDylib(JITDylib &JD) override;
  89.   Error teardownJITDylib(JITDylib &JD) override;
  90.   Error notifyAdding(ResourceTracker &RT,
  91.                      const MaterializationUnit &MU) override;
  92.   Error notifyRemoving(ResourceTracker &RT) override;
  93.  
  94.   /// Returns an AliasMap containing the default aliases for the MachOPlatform.
  95.   /// This can be modified by clients when constructing the platform to add
  96.   /// or remove aliases.
  97.   static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES);
  98.  
  99.   /// Returns the array of required CXX aliases.
  100.   static ArrayRef<std::pair<const char *, const char *>> requiredCXXAliases();
  101.  
  102.   /// Returns the array of standard runtime utility aliases for MachO.
  103.   static ArrayRef<std::pair<const char *, const char *>>
  104.   standardRuntimeUtilityAliases();
  105.  
  106.   /// Returns true if the given section name is an initializer section.
  107.   static bool isInitializerSection(StringRef SegName, StringRef SectName);
  108.  
  109. private:
  110.   // Data needed for bootstrap only.
  111.   struct BootstrapInfo {
  112.     std::mutex Mutex;
  113.     std::condition_variable CV;
  114.     size_t ActiveGraphs = 0;
  115.     shared::AllocActions DeferredAAs;
  116.     ExecutorAddr MachOHeaderAddr;
  117.   };
  118.  
  119.   // The MachOPlatformPlugin scans/modifies LinkGraphs to support MachO
  120.   // platform features including initializers, exceptions, TLV, and language
  121.   // runtime registration.
  122.   class MachOPlatformPlugin : public ObjectLinkingLayer::Plugin {
  123.   public:
  124.     MachOPlatformPlugin(MachOPlatform &MP) : MP(MP) {}
  125.  
  126.     void modifyPassConfig(MaterializationResponsibility &MR,
  127.                           jitlink::LinkGraph &G,
  128.                           jitlink::PassConfiguration &Config) override;
  129.  
  130.     SyntheticSymbolDependenciesMap
  131.     getSyntheticSymbolDependencies(MaterializationResponsibility &MR) override;
  132.  
  133.     // FIXME: We should be tentatively tracking scraped sections and discarding
  134.     // if the MR fails.
  135.     Error notifyFailed(MaterializationResponsibility &MR) override {
  136.       return Error::success();
  137.     }
  138.  
  139.     Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
  140.       return Error::success();
  141.     }
  142.  
  143.     void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
  144.                                      ResourceKey SrcKey) override {}
  145.  
  146.   private:
  147.     using InitSymbolDepMap =
  148.         DenseMap<MaterializationResponsibility *, JITLinkSymbolSet>;
  149.  
  150.     struct UnwindSections {
  151.       SmallVector<ExecutorAddrRange> CodeRanges;
  152.       ExecutorAddrRange DwarfSection;
  153.       ExecutorAddrRange CompactUnwindSection;
  154.     };
  155.  
  156.     Error bootstrapPipelineStart(jitlink::LinkGraph &G);
  157.     Error bootstrapPipelineRecordRuntimeFunctions(jitlink::LinkGraph &G);
  158.     Error bootstrapPipelineEnd(jitlink::LinkGraph &G);
  159.  
  160.     Error recordRuntimeRegistrationFunctions(jitlink::LinkGraph &G);
  161.  
  162.     Error associateJITDylibHeaderSymbol(jitlink::LinkGraph &G,
  163.                                         MaterializationResponsibility &MR);
  164.  
  165.     Error preserveInitSections(jitlink::LinkGraph &G,
  166.                                MaterializationResponsibility &MR);
  167.  
  168.     Error processObjCImageInfo(jitlink::LinkGraph &G,
  169.                                MaterializationResponsibility &MR);
  170.  
  171.     Error fixTLVSectionsAndEdges(jitlink::LinkGraph &G, JITDylib &JD);
  172.  
  173.     std::optional<UnwindSections> findUnwindSectionInfo(jitlink::LinkGraph &G);
  174.  
  175.     Error registerObjectPlatformSections(jitlink::LinkGraph &G, JITDylib &JD,
  176.                                          bool InBootstrapPhase);
  177.  
  178.     std::mutex PluginMutex;
  179.     MachOPlatform &MP;
  180.  
  181.     // FIXME: ObjCImageInfos and HeaderAddrs need to be cleared when
  182.     // JITDylibs are removed.
  183.     DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;
  184.     DenseMap<JITDylib *, ExecutorAddr> HeaderAddrs;
  185.     InitSymbolDepMap InitSymbolDeps;
  186.   };
  187.  
  188.   using GetJITDylibHeaderSendResultFn =
  189.       unique_function<void(Expected<ExecutorAddr>)>;
  190.   using GetJITDylibNameSendResultFn =
  191.       unique_function<void(Expected<StringRef>)>;
  192.   using PushInitializersSendResultFn =
  193.       unique_function<void(Expected<MachOJITDylibDepInfoMap>)>;
  194.   using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
  195.  
  196.   static bool supportedTarget(const Triple &TT);
  197.  
  198.   MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
  199.                 JITDylib &PlatformJD,
  200.                 std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
  201.                 Error &Err);
  202.  
  203.   // Associate MachOPlatform JIT-side runtime support functions with handlers.
  204.   Error associateRuntimeSupportFunctions();
  205.  
  206.   // Implements rt_pushInitializers by making repeat async lookups for
  207.   // initializer symbols (each lookup may spawn more initializer symbols if
  208.   // it pulls in new materializers, e.g. from objects in a static library).
  209.   void pushInitializersLoop(PushInitializersSendResultFn SendResult,
  210.                             JITDylibSP JD);
  211.  
  212.   // Handle requests from the ORC runtime to push MachO initializer info.
  213.   void rt_pushInitializers(PushInitializersSendResultFn SendResult,
  214.                            ExecutorAddr JDHeaderAddr);
  215.  
  216.   // Handle requests for symbol addresses from the ORC runtime.
  217.   void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
  218.                        StringRef SymbolName);
  219.  
  220.   // Call the ORC runtime to create a pthread key.
  221.   Expected<uint64_t> createPThreadKey();
  222.  
  223.   ExecutionSession &ES;
  224.   JITDylib &PlatformJD;
  225.   ObjectLinkingLayer &ObjLinkingLayer;
  226.  
  227.   SymbolStringPtr MachOHeaderStartSymbol = ES.intern("___dso_handle");
  228.  
  229.   struct RuntimeFunction {
  230.     RuntimeFunction(SymbolStringPtr Name) : Name(std::move(Name)) {}
  231.     SymbolStringPtr Name;
  232.     ExecutorAddr Addr;
  233.   };
  234.  
  235.   RuntimeFunction PlatformBootstrap{
  236.       ES.intern("___orc_rt_macho_platform_bootstrap")};
  237.   RuntimeFunction PlatformShutdown{
  238.       ES.intern("___orc_rt_macho_platform_shutdown")};
  239.   RuntimeFunction RegisterEHFrameSection{
  240.       ES.intern("___orc_rt_macho_register_ehframe_section")};
  241.   RuntimeFunction DeregisterEHFrameSection{
  242.       ES.intern("___orc_rt_macho_deregister_ehframe_section")};
  243.   RuntimeFunction RegisterJITDylib{
  244.       ES.intern("___orc_rt_macho_register_jitdylib")};
  245.   RuntimeFunction DeregisterJITDylib{
  246.       ES.intern("___orc_rt_macho_deregister_jitdylib")};
  247.   RuntimeFunction RegisterObjectPlatformSections{
  248.       ES.intern("___orc_rt_macho_register_object_platform_sections")};
  249.   RuntimeFunction DeregisterObjectPlatformSections{
  250.       ES.intern("___orc_rt_macho_deregister_object_platform_sections")};
  251.   RuntimeFunction CreatePThreadKey{
  252.       ES.intern("___orc_rt_macho_create_pthread_key")};
  253.  
  254.   DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
  255.  
  256.   std::mutex PlatformMutex;
  257.   DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr;
  258.   DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib;
  259.   DenseMap<JITDylib *, uint64_t> JITDylibToPThreadKey;
  260.  
  261.   std::atomic<BootstrapInfo *> Bootstrap;
  262. };
  263.  
  264. namespace shared {
  265.  
  266. using SPSNamedExecutorAddrRangeSequence =
  267.     SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRange>>;
  268.  
  269. } // end namespace shared
  270. } // end namespace orc
  271. } // end namespace llvm
  272.  
  273. #endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
  274.