Home | History | Annotate | Download | only in MCJIT
      1 //===-- MCJIT.h - Class definition for the MCJIT ----------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
     11 #define LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
     12 
     13 #include "llvm/ADT/SmallPtrSet.h"
     14 #include "llvm/ADT/SmallVector.h"
     15 #include "llvm/ExecutionEngine/ExecutionEngine.h"
     16 #include "llvm/ExecutionEngine/ObjectCache.h"
     17 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
     18 #include "llvm/ExecutionEngine/RuntimeDyld.h"
     19 #include "llvm/IR/Module.h"
     20 #include "llvm/Support/SmallVectorMemoryBuffer.h"
     21 
     22 namespace llvm {
     23 class MCJIT;
     24 
     25 // This is a helper class that the MCJIT execution engine uses for linking
     26 // functions across modules that it owns.  It aggregates the memory manager
     27 // that is passed in to the MCJIT constructor and defers most functionality
     28 // to that object.
     29 class LinkingSymbolResolver : public LegacyJITSymbolResolver {
     30 public:
     31   LinkingSymbolResolver(MCJIT &Parent,
     32                         std::shared_ptr<LegacyJITSymbolResolver> Resolver)
     33       : ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}
     34 
     35   JITSymbol findSymbol(const std::string &Name) override;
     36 
     37   // MCJIT doesn't support logical dylibs.
     38   JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
     39     return nullptr;
     40   }
     41 
     42 private:
     43   MCJIT &ParentEngine;
     44   std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
     45   void anchor() override;
     46 };
     47 
     48 // About Module states: added->loaded->finalized.
     49 //
     50 // The purpose of the "added" state is having modules in standby. (added=known
     51 // but not compiled). The idea is that you can add a module to provide function
     52 // definitions but if nothing in that module is referenced by a module in which
     53 // a function is executed (note the wording here because it's not exactly the
     54 // ideal case) then the module never gets compiled. This is sort of lazy
     55 // compilation.
     56 //
     57 // The purpose of the "loaded" state (loaded=compiled and required sections
     58 // copied into local memory but not yet ready for execution) is to have an
     59 // intermediate state wherein clients can remap the addresses of sections, using
     60 // MCJIT::mapSectionAddress, (in preparation for later copying to a new location
     61 // or an external process) before relocations and page permissions are applied.
     62 //
     63 // It might not be obvious at first glance, but the "remote-mcjit" case in the
     64 // lli tool does this.  In that case, the intermediate action is taken by the
     65 // RemoteMemoryManager in response to the notifyObjectLoaded function being
     66 // called.
     67 
     68 class MCJIT : public ExecutionEngine {
     69   MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
     70         std::shared_ptr<MCJITMemoryManager> MemMgr,
     71         std::shared_ptr<LegacyJITSymbolResolver> Resolver);
     72 
     73   typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet;
     74 
     75   class OwningModuleContainer {
     76   public:
     77     OwningModuleContainer() {
     78     }
     79     ~OwningModuleContainer() {
     80       freeModulePtrSet(AddedModules);
     81       freeModulePtrSet(LoadedModules);
     82       freeModulePtrSet(FinalizedModules);
     83     }
     84 
     85     ModulePtrSet::iterator begin_added() { return AddedModules.begin(); }
     86     ModulePtrSet::iterator end_added() { return AddedModules.end(); }
     87     iterator_range<ModulePtrSet::iterator> added() {
     88       return make_range(begin_added(), end_added());
     89     }
     90 
     91     ModulePtrSet::iterator begin_loaded() { return LoadedModules.begin(); }
     92     ModulePtrSet::iterator end_loaded() { return LoadedModules.end(); }
     93 
     94     ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); }
     95     ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); }
     96 
     97     void addModule(std::unique_ptr<Module> M) {
     98       AddedModules.insert(M.release());
     99     }
    100 
    101     bool removeModule(Module *M) {
    102       return AddedModules.erase(M) || LoadedModules.erase(M) ||
    103              FinalizedModules.erase(M);
    104     }
    105 
    106     bool hasModuleBeenAddedButNotLoaded(Module *M) {
    107       return AddedModules.count(M) != 0;
    108     }
    109 
    110     bool hasModuleBeenLoaded(Module *M) {
    111       // If the module is in either the "loaded" or "finalized" sections it
    112       // has been loaded.
    113       return (LoadedModules.count(M) != 0 ) || (FinalizedModules.count(M) != 0);
    114     }
    115 
    116     bool hasModuleBeenFinalized(Module *M) {
    117       return FinalizedModules.count(M) != 0;
    118     }
    119 
    120     bool ownsModule(Module* M) {
    121       return (AddedModules.count(M) != 0) || (LoadedModules.count(M) != 0) ||
    122              (FinalizedModules.count(M) != 0);
    123     }
    124 
    125     void markModuleAsLoaded(Module *M) {
    126       // This checks against logic errors in the MCJIT implementation.
    127       // This function should never be called with either a Module that MCJIT
    128       // does not own or a Module that has already been loaded and/or finalized.
    129       assert(AddedModules.count(M) &&
    130              "markModuleAsLoaded: Module not found in AddedModules");
    131 
    132       // Remove the module from the "Added" set.
    133       AddedModules.erase(M);
    134 
    135       // Add the Module to the "Loaded" set.
    136       LoadedModules.insert(M);
    137     }
    138 
    139     void markModuleAsFinalized(Module *M) {
    140       // This checks against logic errors in the MCJIT implementation.
    141       // This function should never be called with either a Module that MCJIT
    142       // does not own, a Module that has not been loaded or a Module that has
    143       // already been finalized.
    144       assert(LoadedModules.count(M) &&
    145              "markModuleAsFinalized: Module not found in LoadedModules");
    146 
    147       // Remove the module from the "Loaded" section of the list.
    148       LoadedModules.erase(M);
    149 
    150       // Add the Module to the "Finalized" section of the list by inserting it
    151       // before the 'end' iterator.
    152       FinalizedModules.insert(M);
    153     }
    154 
    155     void markAllLoadedModulesAsFinalized() {
    156       for (ModulePtrSet::iterator I = LoadedModules.begin(),
    157                                   E = LoadedModules.end();
    158            I != E; ++I) {
    159         Module *M = *I;
    160         FinalizedModules.insert(M);
    161       }
    162       LoadedModules.clear();
    163     }
    164 
    165   private:
    166     ModulePtrSet AddedModules;
    167     ModulePtrSet LoadedModules;
    168     ModulePtrSet FinalizedModules;
    169 
    170     void freeModulePtrSet(ModulePtrSet& MPS) {
    171       // Go through the module set and delete everything.
    172       for (ModulePtrSet::iterator I = MPS.begin(), E = MPS.end(); I != E; ++I) {
    173         Module *M = *I;
    174         delete M;
    175       }
    176       MPS.clear();
    177     }
    178   };
    179 
    180   std::unique_ptr<TargetMachine> TM;
    181   MCContext *Ctx;
    182   std::shared_ptr<MCJITMemoryManager> MemMgr;
    183   LinkingSymbolResolver Resolver;
    184   RuntimeDyld Dyld;
    185   std::vector<JITEventListener*> EventListeners;
    186 
    187   OwningModuleContainer OwnedModules;
    188 
    189   SmallVector<object::OwningBinary<object::Archive>, 2> Archives;
    190   SmallVector<std::unique_ptr<MemoryBuffer>, 2> Buffers;
    191 
    192   SmallVector<std::unique_ptr<object::ObjectFile>, 2> LoadedObjects;
    193 
    194   // An optional ObjectCache to be notified of compiled objects and used to
    195   // perform lookup of pre-compiled code to avoid re-compilation.
    196   ObjectCache *ObjCache;
    197 
    198   Function *FindFunctionNamedInModulePtrSet(StringRef FnName,
    199                                             ModulePtrSet::iterator I,
    200                                             ModulePtrSet::iterator E);
    201 
    202   GlobalVariable *FindGlobalVariableNamedInModulePtrSet(StringRef Name,
    203                                                         bool AllowInternal,
    204                                                         ModulePtrSet::iterator I,
    205                                                         ModulePtrSet::iterator E);
    206 
    207   void runStaticConstructorsDestructorsInModulePtrSet(bool isDtors,
    208                                                       ModulePtrSet::iterator I,
    209                                                       ModulePtrSet::iterator E);
    210 
    211 public:
    212   ~MCJIT() override;
    213 
    214   /// @name ExecutionEngine interface implementation
    215   /// @{
    216   void addModule(std::unique_ptr<Module> M) override;
    217   void addObjectFile(std::unique_ptr<object::ObjectFile> O) override;
    218   void addObjectFile(object::OwningBinary<object::ObjectFile> O) override;
    219   void addArchive(object::OwningBinary<object::Archive> O) override;
    220   bool removeModule(Module *M) override;
    221 
    222   /// FindFunctionNamed - Search all of the active modules to find the function that
    223   /// defines FnName.  This is very slow operation and shouldn't be used for
    224   /// general code.
    225   Function *FindFunctionNamed(StringRef FnName) override;
    226 
    227   /// FindGlobalVariableNamed - Search all of the active modules to find the
    228   /// global variable that defines Name.  This is very slow operation and
    229   /// shouldn't be used for general code.
    230   GlobalVariable *FindGlobalVariableNamed(StringRef Name,
    231                                           bool AllowInternal = false) override;
    232 
    233   /// Sets the object manager that MCJIT should use to avoid compilation.
    234   void setObjectCache(ObjectCache *manager) override;
    235 
    236   void setProcessAllSections(bool ProcessAllSections) override {
    237     Dyld.setProcessAllSections(ProcessAllSections);
    238   }
    239 
    240   void generateCodeForModule(Module *M) override;
    241 
    242   /// finalizeObject - ensure the module is fully processed and is usable.
    243   ///
    244   /// It is the user-level function for completing the process of making the
    245   /// object usable for execution. It should be called after sections within an
    246   /// object have been relocated using mapSectionAddress.  When this method is
    247   /// called the MCJIT execution engine will reapply relocations for a loaded
    248   /// object.
    249   /// Is it OK to finalize a set of modules, add modules and finalize again.
    250   // FIXME: Do we really need both of these?
    251   void finalizeObject() override;
    252   virtual void finalizeModule(Module *);
    253   void finalizeLoadedModules();
    254 
    255   /// runStaticConstructorsDestructors - This method is used to execute all of
    256   /// the static constructors or destructors for a program.
    257   ///
    258   /// \param isDtors - Run the destructors instead of constructors.
    259   void runStaticConstructorsDestructors(bool isDtors) override;
    260 
    261   void *getPointerToFunction(Function *F) override;
    262 
    263   GenericValue runFunction(Function *F,
    264                            ArrayRef<GenericValue> ArgValues) override;
    265 
    266   /// getPointerToNamedFunction - This method returns the address of the
    267   /// specified function by using the dlsym function call.  As such it is only
    268   /// useful for resolving library symbols, not code generated symbols.
    269   ///
    270   /// If AbortOnFailure is false and no function with the given name is
    271   /// found, this function silently returns a null pointer. Otherwise,
    272   /// it prints a message to stderr and aborts.
    273   ///
    274   void *getPointerToNamedFunction(StringRef Name,
    275                                   bool AbortOnFailure = true) override;
    276 
    277   /// mapSectionAddress - map a section to its target address space value.
    278   /// Map the address of a JIT section as returned from the memory manager
    279   /// to the address in the target process as the running code will see it.
    280   /// This is the address which will be used for relocation resolution.
    281   void mapSectionAddress(const void *LocalAddress,
    282                          uint64_t TargetAddress) override {
    283     Dyld.mapSectionAddress(LocalAddress, TargetAddress);
    284   }
    285   void RegisterJITEventListener(JITEventListener *L) override;
    286   void UnregisterJITEventListener(JITEventListener *L) override;
    287 
    288   // If successful, these function will implicitly finalize all loaded objects.
    289   // To get a function address within MCJIT without causing a finalize, use
    290   // getSymbolAddress.
    291   uint64_t getGlobalValueAddress(const std::string &Name) override;
    292   uint64_t getFunctionAddress(const std::string &Name) override;
    293 
    294   TargetMachine *getTargetMachine() override { return TM.get(); }
    295 
    296   /// @}
    297   /// @name (Private) Registration Interfaces
    298   /// @{
    299 
    300   static void Register() {
    301     MCJITCtor = createJIT;
    302   }
    303 
    304   static ExecutionEngine *
    305   createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
    306             std::shared_ptr<MCJITMemoryManager> MemMgr,
    307             std::shared_ptr<LegacyJITSymbolResolver> Resolver,
    308             std::unique_ptr<TargetMachine> TM);
    309 
    310   // @}
    311 
    312   // Takes a mangled name and returns the corresponding JITSymbol (if a
    313   // definition of that mangled name has been added to the JIT).
    314   JITSymbol findSymbol(const std::string &Name, bool CheckFunctionsOnly);
    315 
    316   // DEPRECATED - Please use findSymbol instead.
    317   //
    318   // This is not directly exposed via the ExecutionEngine API, but it is
    319   // used by the LinkingMemoryManager.
    320   //
    321   // getSymbolAddress takes an unmangled name and returns the corresponding
    322   // JITSymbol if a definition of the name has been added to the JIT.
    323   uint64_t getSymbolAddress(const std::string &Name,
    324                             bool CheckFunctionsOnly);
    325 
    326 protected:
    327   /// emitObject -- Generate a JITed object in memory from the specified module
    328   /// Currently, MCJIT only supports a single module and the module passed to
    329   /// this function call is expected to be the contained module.  The module
    330   /// is passed as a parameter here to prepare for multiple module support in
    331   /// the future.
    332   std::unique_ptr<MemoryBuffer> emitObject(Module *M);
    333 
    334   void NotifyObjectEmitted(const object::ObjectFile& Obj,
    335                            const RuntimeDyld::LoadedObjectInfo &L);
    336   void NotifyFreeingObject(const object::ObjectFile& Obj);
    337 
    338   JITSymbol findExistingSymbol(const std::string &Name);
    339   Module *findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly);
    340 };
    341 
    342 } // end llvm namespace
    343 
    344 #endif // LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
    345