Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===--- COFFPlatform.h -- Utilities for executing COFF 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 COFF in Orc.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_EXECUTIONENGINE_ORC_COFFPLATFORM_H
  14. #define LLVM_EXECUTIONENGINE_ORC_COFFPLATFORM_H
  15.  
  16. #include "llvm/ADT/StringRef.h"
  17. #include "llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h"
  18. #include "llvm/ExecutionEngine/Orc/Core.h"
  19. #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
  20. #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
  21. #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
  22. #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
  23.  
  24. #include <future>
  25. #include <memory>
  26. #include <thread>
  27. #include <vector>
  28.  
  29. namespace llvm {
  30. namespace orc {
  31.  
  32. /// Mediates between COFF initialization and ExecutionSession state.
  33. class COFFPlatform : public Platform {
  34. public:
  35.   /// A function that will be called with the name of dll file that must be
  36.   /// loaded.
  37.   using LoadDynamicLibrary =
  38.       unique_function<Error(JITDylib &JD, StringRef DLLFileName)>;
  39.  
  40.   /// Try to create a COFFPlatform instance, adding the ORC runtime to the
  41.   /// given JITDylib.
  42.   static Expected<std::unique_ptr<COFFPlatform>>
  43.   Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
  44.          JITDylib &PlatformJD, const char *OrcRuntimePath,
  45.          LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime = false,
  46.          const char *VCRuntimePath = nullptr,
  47.          std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
  48.  
  49.   ExecutionSession &getExecutionSession() const { return ES; }
  50.   ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
  51.  
  52.   Error setupJITDylib(JITDylib &JD) override;
  53.   Error teardownJITDylib(JITDylib &JD) override;
  54.   Error notifyAdding(ResourceTracker &RT,
  55.                      const MaterializationUnit &MU) override;
  56.   Error notifyRemoving(ResourceTracker &RT) override;
  57.  
  58.   /// Returns an AliasMap containing the default aliases for the COFFPlatform.
  59.   /// This can be modified by clients when constructing the platform to add
  60.   /// or remove aliases.
  61.   static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES);
  62.  
  63.   /// Returns the array of required CXX aliases.
  64.   static ArrayRef<std::pair<const char *, const char *>> requiredCXXAliases();
  65.  
  66.   /// Returns the array of standard runtime utility aliases for COFF.
  67.   static ArrayRef<std::pair<const char *, const char *>>
  68.   standardRuntimeUtilityAliases();
  69.  
  70.   static bool isInitializerSection(StringRef Name) {
  71.     return Name.startswith(".CRT");
  72.   }
  73.  
  74.   static StringRef getSEHFrameSectionName() { return ".pdata"; }
  75.  
  76. private:
  77.   using COFFJITDylibDepInfo = std::vector<ExecutorAddr>;
  78.   using COFFJITDylibDepInfoMap =
  79.       std::vector<std::pair<ExecutorAddr, COFFJITDylibDepInfo>>;
  80.   using COFFObjectSectionsMap =
  81.       SmallVector<std::pair<std::string, ExecutorAddrRange>>;
  82.   using PushInitializersSendResultFn =
  83.       unique_function<void(Expected<COFFJITDylibDepInfoMap>)>;
  84.   using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
  85.   using JITDylibDepMap = DenseMap<JITDylib *, SmallVector<JITDylib *>>;
  86.  
  87.   // The COFFPlatformPlugin scans/modifies LinkGraphs to support COFF
  88.   // platform features including initializers, exceptions, and language
  89.   // runtime registration.
  90.   class COFFPlatformPlugin : public ObjectLinkingLayer::Plugin {
  91.   public:
  92.     COFFPlatformPlugin(COFFPlatform &CP) : CP(CP) {}
  93.  
  94.     void modifyPassConfig(MaterializationResponsibility &MR,
  95.                           jitlink::LinkGraph &G,
  96.                           jitlink::PassConfiguration &Config) override;
  97.  
  98.     SyntheticSymbolDependenciesMap
  99.     getSyntheticSymbolDependencies(MaterializationResponsibility &MR) override;
  100.  
  101.     // FIXME: We should be tentatively tracking scraped sections and discarding
  102.     // if the MR fails.
  103.     Error notifyFailed(MaterializationResponsibility &MR) override {
  104.       return Error::success();
  105.     }
  106.  
  107.     Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
  108.       return Error::success();
  109.     }
  110.  
  111.     void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
  112.                                      ResourceKey SrcKey) override {}
  113.  
  114.   private:
  115.     using InitSymbolDepMap =
  116.         DenseMap<MaterializationResponsibility *, JITLinkSymbolSet>;
  117.  
  118.     Error associateJITDylibHeaderSymbol(jitlink::LinkGraph &G,
  119.                                         MaterializationResponsibility &MR,
  120.                                         bool Bootstrap);
  121.  
  122.     Error preserveInitializerSections(jitlink::LinkGraph &G,
  123.                                       MaterializationResponsibility &MR);
  124.     Error registerObjectPlatformSections(jitlink::LinkGraph &G, JITDylib &JD);
  125.     Error registerObjectPlatformSectionsInBootstrap(jitlink::LinkGraph &G,
  126.                                                     JITDylib &JD);
  127.  
  128.     std::mutex PluginMutex;
  129.     COFFPlatform &CP;
  130.     InitSymbolDepMap InitSymbolDeps;
  131.   };
  132.  
  133.   struct JDBootstrapState {
  134.     JITDylib *JD = nullptr;
  135.     std::string JDName;
  136.     ExecutorAddr HeaderAddr;
  137.     std::list<COFFObjectSectionsMap> ObjectSectionsMaps;
  138.     SmallVector<std::pair<std::string, ExecutorAddr>> Initializers;
  139.   };
  140.  
  141.   static bool supportedTarget(const Triple &TT);
  142.  
  143.   COFFPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
  144.                JITDylib &PlatformJD, const char *OrcRuntimePath,
  145.                LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
  146.                const char *VCRuntimePath, Error &Err);
  147.  
  148.   // Associate COFFPlatform JIT-side runtime support functions with handlers.
  149.   Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
  150.  
  151.   // Records the addresses of runtime symbols used by the platform.
  152.   Error bootstrapCOFFRuntime(JITDylib &PlatformJD);
  153.  
  154.   // Run a specific void function if it exists.
  155.   Error runSymbolIfExists(JITDylib &PlatformJD, StringRef SymbolName);
  156.  
  157.   // Run collected initializers in boostrap stage.
  158.   Error runBootstrapInitializers(JDBootstrapState &BState);
  159.   Error runBootstrapSubsectionInitializers(JDBootstrapState &BState,
  160.                                            StringRef Start, StringRef End);
  161.  
  162.   // Build dependency graph of a JITDylib
  163.   Expected<JITDylibDepMap> buildJDDepMap(JITDylib &JD);
  164.  
  165.   Expected<MemoryBufferRef> getPerJDObjectFile();
  166.  
  167.   // Implements rt_pushInitializers by making repeat async lookups for
  168.   // initializer symbols (each lookup may spawn more initializer symbols if
  169.   // it pulls in new materializers, e.g. from objects in a static library).
  170.   void pushInitializersLoop(PushInitializersSendResultFn SendResult,
  171.                             JITDylibSP JD, JITDylibDepMap &JDDepMap);
  172.  
  173.   void rt_pushInitializers(PushInitializersSendResultFn SendResult,
  174.                            ExecutorAddr JDHeaderAddr);
  175.  
  176.   void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
  177.                        StringRef SymbolName);
  178.  
  179.   ExecutionSession &ES;
  180.   ObjectLinkingLayer &ObjLinkingLayer;
  181.  
  182.   LoadDynamicLibrary LoadDynLibrary;
  183.   std::unique_ptr<COFFVCRuntimeBootstrapper> VCRuntimeBootstrap;
  184.   std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer;
  185.   std::unique_ptr<object::Archive> OrcRuntimeArchive;
  186.   bool StaticVCRuntime;
  187.  
  188.   SymbolStringPtr COFFHeaderStartSymbol;
  189.  
  190.   // State of bootstrap in progress
  191.   std::map<JITDylib *, JDBootstrapState> JDBootstrapStates;
  192.   std::atomic<bool> Bootstrapping;
  193.  
  194.   ExecutorAddr orc_rt_coff_platform_bootstrap;
  195.   ExecutorAddr orc_rt_coff_platform_shutdown;
  196.   ExecutorAddr orc_rt_coff_register_object_sections;
  197.   ExecutorAddr orc_rt_coff_deregister_object_sections;
  198.   ExecutorAddr orc_rt_coff_register_jitdylib;
  199.   ExecutorAddr orc_rt_coff_deregister_jitdylib;
  200.  
  201.   DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr;
  202.   DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib;
  203.  
  204.   DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
  205.  
  206.   std::set<std::string> DylibsToPreload;
  207.  
  208.   std::mutex PlatformMutex;
  209. };
  210.  
  211. } // end namespace orc
  212. } // end namespace llvm
  213.  
  214. #endif // LLVM_EXECUTIONENGINE_ORC_COFFPLATFORM_H
  215.