Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:52

0001 //===--- COFFPlatform.h -- Utilities for executing COFF in Orc --*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Utilities for executing JIT'd COFF in Orc.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_EXECUTIONENGINE_ORC_COFFPLATFORM_H
0014 #define LLVM_EXECUTIONENGINE_ORC_COFFPLATFORM_H
0015 
0016 #include "llvm/ADT/StringRef.h"
0017 #include "llvm/ExecutionEngine/Orc/COFFVCRuntimeSupport.h"
0018 #include "llvm/ExecutionEngine/Orc/Core.h"
0019 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
0020 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
0021 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
0022 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
0023 
0024 #include <future>
0025 #include <list>
0026 #include <memory>
0027 #include <thread>
0028 #include <vector>
0029 
0030 namespace llvm {
0031 namespace orc {
0032 
0033 /// Mediates between COFF initialization and ExecutionSession state.
0034 class COFFPlatform : public Platform {
0035 public:
0036   /// A function that will be called with the name of dll file that must be
0037   /// loaded.
0038   using LoadDynamicLibrary =
0039       unique_function<Error(JITDylib &JD, StringRef DLLFileName)>;
0040 
0041   /// Try to create a COFFPlatform instance, adding the ORC runtime to the
0042   /// given JITDylib.
0043   static Expected<std::unique_ptr<COFFPlatform>>
0044   Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
0045          std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer,
0046          LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime = false,
0047          const char *VCRuntimePath = nullptr,
0048          std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
0049 
0050   static Expected<std::unique_ptr<COFFPlatform>>
0051   Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
0052          const char *OrcRuntimePath, LoadDynamicLibrary LoadDynLibrary,
0053          bool StaticVCRuntime = false, const char *VCRuntimePath = nullptr,
0054          std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
0055 
0056   ExecutionSession &getExecutionSession() const { return ES; }
0057   ObjectLinkingLayer &getObjectLinkingLayer() const { return ObjLinkingLayer; }
0058 
0059   Error setupJITDylib(JITDylib &JD) override;
0060   Error teardownJITDylib(JITDylib &JD) override;
0061   Error notifyAdding(ResourceTracker &RT,
0062                      const MaterializationUnit &MU) override;
0063   Error notifyRemoving(ResourceTracker &RT) override;
0064 
0065   /// Returns an AliasMap containing the default aliases for the COFFPlatform.
0066   /// This can be modified by clients when constructing the platform to add
0067   /// or remove aliases.
0068   static SymbolAliasMap standardPlatformAliases(ExecutionSession &ES);
0069 
0070   /// Returns the array of required CXX aliases.
0071   static ArrayRef<std::pair<const char *, const char *>> requiredCXXAliases();
0072 
0073   /// Returns the array of standard runtime utility aliases for COFF.
0074   static ArrayRef<std::pair<const char *, const char *>>
0075   standardRuntimeUtilityAliases();
0076 
0077   static StringRef getSEHFrameSectionName() { return ".pdata"; }
0078 
0079 private:
0080   using COFFJITDylibDepInfo = std::vector<ExecutorAddr>;
0081   using COFFJITDylibDepInfoMap =
0082       std::vector<std::pair<ExecutorAddr, COFFJITDylibDepInfo>>;
0083   using COFFObjectSectionsMap =
0084       SmallVector<std::pair<std::string, ExecutorAddrRange>>;
0085   using PushInitializersSendResultFn =
0086       unique_function<void(Expected<COFFJITDylibDepInfoMap>)>;
0087   using SendSymbolAddressFn = unique_function<void(Expected<ExecutorAddr>)>;
0088   using JITDylibDepMap = DenseMap<JITDylib *, SmallVector<JITDylib *>>;
0089 
0090   // The COFFPlatformPlugin scans/modifies LinkGraphs to support COFF
0091   // platform features including initializers, exceptions, and language
0092   // runtime registration.
0093   class COFFPlatformPlugin : public ObjectLinkingLayer::Plugin {
0094   public:
0095     COFFPlatformPlugin(COFFPlatform &CP) : CP(CP) {}
0096 
0097     void modifyPassConfig(MaterializationResponsibility &MR,
0098                           jitlink::LinkGraph &G,
0099                           jitlink::PassConfiguration &Config) override;
0100 
0101     // FIXME: We should be tentatively tracking scraped sections and discarding
0102     // if the MR fails.
0103     Error notifyFailed(MaterializationResponsibility &MR) override {
0104       return Error::success();
0105     }
0106 
0107     Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
0108       return Error::success();
0109     }
0110 
0111     void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
0112                                      ResourceKey SrcKey) override {}
0113 
0114   private:
0115     Error associateJITDylibHeaderSymbol(jitlink::LinkGraph &G,
0116                                         MaterializationResponsibility &MR,
0117                                         bool Bootstrap);
0118 
0119     Error preserveInitializerSections(jitlink::LinkGraph &G,
0120                                       MaterializationResponsibility &MR);
0121     Error registerObjectPlatformSections(jitlink::LinkGraph &G, JITDylib &JD);
0122     Error registerObjectPlatformSectionsInBootstrap(jitlink::LinkGraph &G,
0123                                                     JITDylib &JD);
0124 
0125     std::mutex PluginMutex;
0126     COFFPlatform &CP;
0127   };
0128 
0129   struct JDBootstrapState {
0130     JITDylib *JD = nullptr;
0131     std::string JDName;
0132     ExecutorAddr HeaderAddr;
0133     std::list<COFFObjectSectionsMap> ObjectSectionsMaps;
0134     SmallVector<std::pair<std::string, ExecutorAddr>> Initializers;
0135   };
0136 
0137   static bool supportedTarget(const Triple &TT);
0138 
0139   COFFPlatform(
0140       ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
0141       std::unique_ptr<StaticLibraryDefinitionGenerator> OrcRuntimeGenerator,
0142       std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer,
0143       std::unique_ptr<object::Archive> OrcRuntimeArchive,
0144       LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
0145       const char *VCRuntimePath, Error &Err);
0146 
0147   // Associate COFFPlatform JIT-side runtime support functions with handlers.
0148   Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
0149 
0150   // Records the addresses of runtime symbols used by the platform.
0151   Error bootstrapCOFFRuntime(JITDylib &PlatformJD);
0152 
0153   // Run a specific void function if it exists.
0154   Error runSymbolIfExists(JITDylib &PlatformJD, StringRef SymbolName);
0155 
0156   // Run collected initializers in boostrap stage.
0157   Error runBootstrapInitializers(JDBootstrapState &BState);
0158   Error runBootstrapSubsectionInitializers(JDBootstrapState &BState,
0159                                            StringRef Start, StringRef End);
0160 
0161   // Build dependency graph of a JITDylib
0162   Expected<JITDylibDepMap> buildJDDepMap(JITDylib &JD);
0163 
0164   Expected<MemoryBufferRef> getPerJDObjectFile();
0165 
0166   // Implements rt_pushInitializers by making repeat async lookups for
0167   // initializer symbols (each lookup may spawn more initializer symbols if
0168   // it pulls in new materializers, e.g. from objects in a static library).
0169   void pushInitializersLoop(PushInitializersSendResultFn SendResult,
0170                             JITDylibSP JD, JITDylibDepMap &JDDepMap);
0171 
0172   void rt_pushInitializers(PushInitializersSendResultFn SendResult,
0173                            ExecutorAddr JDHeaderAddr);
0174 
0175   void rt_lookupSymbol(SendSymbolAddressFn SendResult, ExecutorAddr Handle,
0176                        StringRef SymbolName);
0177 
0178   ExecutionSession &ES;
0179   ObjectLinkingLayer &ObjLinkingLayer;
0180 
0181   LoadDynamicLibrary LoadDynLibrary;
0182   std::unique_ptr<COFFVCRuntimeBootstrapper> VCRuntimeBootstrap;
0183   std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer;
0184   std::unique_ptr<object::Archive> OrcRuntimeArchive;
0185   bool StaticVCRuntime;
0186 
0187   SymbolStringPtr COFFHeaderStartSymbol;
0188 
0189   // State of bootstrap in progress
0190   std::map<JITDylib *, JDBootstrapState> JDBootstrapStates;
0191   std::atomic<bool> Bootstrapping;
0192 
0193   ExecutorAddr orc_rt_coff_platform_bootstrap;
0194   ExecutorAddr orc_rt_coff_platform_shutdown;
0195   ExecutorAddr orc_rt_coff_register_object_sections;
0196   ExecutorAddr orc_rt_coff_deregister_object_sections;
0197   ExecutorAddr orc_rt_coff_register_jitdylib;
0198   ExecutorAddr orc_rt_coff_deregister_jitdylib;
0199 
0200   DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr;
0201   DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib;
0202 
0203   DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
0204 
0205   std::set<std::string> DylibsToPreload;
0206 
0207   std::mutex PlatformMutex;
0208 };
0209 
0210 } // end namespace orc
0211 } // end namespace llvm
0212 
0213 #endif // LLVM_EXECUTIONENGINE_ORC_COFFPLATFORM_H