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_H 11 #define LLVM_LIB_EXECUTIONENGINE_MCJIT_H 12 13 #include "llvm/ADT/DenseMap.h" 14 #include "llvm/ADT/SmallPtrSet.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ExecutionEngine/ExecutionEngine.h" 17 #include "llvm/ExecutionEngine/ObjectCache.h" 18 #include "llvm/ExecutionEngine/ObjectImage.h" 19 #include "llvm/ExecutionEngine/RuntimeDyld.h" 20 #include "llvm/IR/Module.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 LinkingMemoryManager : public RTDyldMemoryManager { 30 public: LinkingMemoryManager(MCJIT * Parent,RTDyldMemoryManager * MM)31 LinkingMemoryManager(MCJIT *Parent, RTDyldMemoryManager *MM) 32 : ParentEngine(Parent), ClientMM(MM) {} 33 34 virtual uint64_t getSymbolAddress(const std::string &Name); 35 36 // Functions deferred to client memory manager allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)37 virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 38 unsigned SectionID, StringRef SectionName) { 39 return ClientMM->allocateCodeSection(Size, Alignment, SectionID, SectionName); 40 } 41 allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName,bool IsReadOnly)42 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 43 unsigned SectionID, StringRef SectionName, 44 bool IsReadOnly) { 45 return ClientMM->allocateDataSection(Size, Alignment, 46 SectionID, SectionName, IsReadOnly); 47 } 48 notifyObjectLoaded(ExecutionEngine * EE,const ObjectImage * Obj)49 virtual void notifyObjectLoaded(ExecutionEngine *EE, 50 const ObjectImage *Obj) { 51 ClientMM->notifyObjectLoaded(EE, Obj); 52 } 53 registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)54 virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) { 55 ClientMM->registerEHFrames(Addr, LoadAddr, Size); 56 } 57 deregisterEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)58 virtual void deregisterEHFrames(uint8_t *Addr, 59 uint64_t LoadAddr, 60 size_t Size) { 61 ClientMM->deregisterEHFrames(Addr, LoadAddr, Size); 62 } 63 64 virtual bool finalizeMemory(std::string *ErrMsg = 0) { 65 return ClientMM->finalizeMemory(ErrMsg); 66 } 67 68 private: 69 MCJIT *ParentEngine; 70 OwningPtr<RTDyldMemoryManager> ClientMM; 71 }; 72 73 // About Module states: added->loaded->finalized. 74 // 75 // The purpose of the "added" state is having modules in standby. (added=known 76 // but not compiled). The idea is that you can add a module to provide function 77 // definitions but if nothing in that module is referenced by a module in which 78 // a function is executed (note the wording here because it's not exactly the 79 // ideal case) then the module never gets compiled. This is sort of lazy 80 // compilation. 81 // 82 // The purpose of the "loaded" state (loaded=compiled and required sections 83 // copied into local memory but not yet ready for execution) is to have an 84 // intermediate state wherein clients can remap the addresses of sections, using 85 // MCJIT::mapSectionAddress, (in preparation for later copying to a new location 86 // or an external process) before relocations and page permissions are applied. 87 // 88 // It might not be obvious at first glance, but the "remote-mcjit" case in the 89 // lli tool does this. In that case, the intermediate action is taken by the 90 // RemoteMemoryManager in response to the notifyObjectLoaded function being 91 // called. 92 93 class MCJIT : public ExecutionEngine { 94 MCJIT(Module *M, TargetMachine *tm, RTDyldMemoryManager *MemMgr, 95 bool AllocateGVsWithCode); 96 97 typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet; 98 99 class OwningModuleContainer { 100 public: OwningModuleContainer()101 OwningModuleContainer() { 102 } ~OwningModuleContainer()103 ~OwningModuleContainer() { 104 freeModulePtrSet(AddedModules); 105 freeModulePtrSet(LoadedModules); 106 freeModulePtrSet(FinalizedModules); 107 } 108 begin_added()109 ModulePtrSet::iterator begin_added() { return AddedModules.begin(); } end_added()110 ModulePtrSet::iterator end_added() { return AddedModules.end(); } 111 begin_loaded()112 ModulePtrSet::iterator begin_loaded() { return LoadedModules.begin(); } end_loaded()113 ModulePtrSet::iterator end_loaded() { return LoadedModules.end(); } 114 begin_finalized()115 ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); } end_finalized()116 ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); } 117 addModule(Module * M)118 void addModule(Module *M) { 119 AddedModules.insert(M); 120 } 121 removeModule(Module * M)122 bool removeModule(Module *M) { 123 return AddedModules.erase(M) || LoadedModules.erase(M) || 124 FinalizedModules.erase(M); 125 } 126 hasModuleBeenAddedButNotLoaded(Module * M)127 bool hasModuleBeenAddedButNotLoaded(Module *M) { 128 return AddedModules.count(M) != 0; 129 } 130 hasModuleBeenLoaded(Module * M)131 bool hasModuleBeenLoaded(Module *M) { 132 // If the module is in either the "loaded" or "finalized" sections it 133 // has been loaded. 134 return (LoadedModules.count(M) != 0 ) || (FinalizedModules.count(M) != 0); 135 } 136 hasModuleBeenFinalized(Module * M)137 bool hasModuleBeenFinalized(Module *M) { 138 return FinalizedModules.count(M) != 0; 139 } 140 ownsModule(Module * M)141 bool ownsModule(Module* M) { 142 return (AddedModules.count(M) != 0) || (LoadedModules.count(M) != 0) || 143 (FinalizedModules.count(M) != 0); 144 } 145 markModuleAsLoaded(Module * M)146 void markModuleAsLoaded(Module *M) { 147 // This checks against logic errors in the MCJIT implementation. 148 // This function should never be called with either a Module that MCJIT 149 // does not own or a Module that has already been loaded and/or finalized. 150 assert(AddedModules.count(M) && 151 "markModuleAsLoaded: Module not found in AddedModules"); 152 153 // Remove the module from the "Added" set. 154 AddedModules.erase(M); 155 156 // Add the Module to the "Loaded" set. 157 LoadedModules.insert(M); 158 } 159 markModuleAsFinalized(Module * M)160 void markModuleAsFinalized(Module *M) { 161 // This checks against logic errors in the MCJIT implementation. 162 // This function should never be called with either a Module that MCJIT 163 // does not own, a Module that has not been loaded or a Module that has 164 // already been finalized. 165 assert(LoadedModules.count(M) && 166 "markModuleAsFinalized: Module not found in LoadedModules"); 167 168 // Remove the module from the "Loaded" section of the list. 169 LoadedModules.erase(M); 170 171 // Add the Module to the "Finalized" section of the list by inserting it 172 // before the 'end' iterator. 173 FinalizedModules.insert(M); 174 } 175 markAllLoadedModulesAsFinalized()176 void markAllLoadedModulesAsFinalized() { 177 for (ModulePtrSet::iterator I = LoadedModules.begin(), 178 E = LoadedModules.end(); 179 I != E; ++I) { 180 Module *M = *I; 181 FinalizedModules.insert(M); 182 } 183 LoadedModules.clear(); 184 } 185 186 private: 187 ModulePtrSet AddedModules; 188 ModulePtrSet LoadedModules; 189 ModulePtrSet FinalizedModules; 190 freeModulePtrSet(ModulePtrSet & MPS)191 void freeModulePtrSet(ModulePtrSet& MPS) { 192 // Go through the module set and delete everything. 193 for (ModulePtrSet::iterator I = MPS.begin(), E = MPS.end(); I != E; ++I) { 194 Module *M = *I; 195 delete M; 196 } 197 MPS.clear(); 198 } 199 }; 200 201 TargetMachine *TM; 202 MCContext *Ctx; 203 LinkingMemoryManager MemMgr; 204 RuntimeDyld Dyld; 205 SmallVector<JITEventListener*, 2> EventListeners; 206 207 OwningModuleContainer OwnedModules; 208 209 typedef DenseMap<Module *, ObjectImage *> LoadedObjectMap; 210 LoadedObjectMap LoadedObjects; 211 212 // An optional ObjectCache to be notified of compiled objects and used to 213 // perform lookup of pre-compiled code to avoid re-compilation. 214 ObjectCache *ObjCache; 215 216 Function *FindFunctionNamedInModulePtrSet(const char *FnName, 217 ModulePtrSet::iterator I, 218 ModulePtrSet::iterator E); 219 220 void runStaticConstructorsDestructorsInModulePtrSet(bool isDtors, 221 ModulePtrSet::iterator I, 222 ModulePtrSet::iterator E); 223 224 public: 225 ~MCJIT(); 226 227 /// @name ExecutionEngine interface implementation 228 /// @{ 229 virtual void addModule(Module *M); 230 virtual bool removeModule(Module *M); 231 232 /// FindFunctionNamed - Search all of the active modules to find the one that 233 /// defines FnName. This is very slow operation and shouldn't be used for 234 /// general code. 235 virtual Function *FindFunctionNamed(const char *FnName); 236 237 /// Sets the object manager that MCJIT should use to avoid compilation. 238 virtual void setObjectCache(ObjectCache *manager); 239 240 virtual void generateCodeForModule(Module *M); 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 virtual void finalizeObject(); 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); 260 261 virtual void *getPointerToBasicBlock(BasicBlock *BB); 262 263 virtual void *getPointerToFunction(Function *F); 264 265 virtual void *recompileAndRelinkFunction(Function *F); 266 267 virtual void freeMachineCodeForFunction(Function *F); 268 269 virtual GenericValue runFunction(Function *F, 270 const std::vector<GenericValue> &ArgValues); 271 272 /// getPointerToNamedFunction - This method returns the address of the 273 /// specified function by using the dlsym function call. As such it is only 274 /// useful for resolving library symbols, not code generated symbols. 275 /// 276 /// If AbortOnFailure is false and no function with the given name is 277 /// found, this function silently returns a null pointer. Otherwise, 278 /// it prints a message to stderr and aborts. 279 /// 280 virtual void *getPointerToNamedFunction(const std::string &Name, 281 bool AbortOnFailure = true); 282 283 /// mapSectionAddress - map a section to its target address space value. 284 /// Map the address of a JIT section as returned from the memory manager 285 /// to the address in the target process as the running code will see it. 286 /// This is the address which will be used for relocation resolution. mapSectionAddress(const void * LocalAddress,uint64_t TargetAddress)287 virtual void mapSectionAddress(const void *LocalAddress, 288 uint64_t TargetAddress) { 289 Dyld.mapSectionAddress(LocalAddress, TargetAddress); 290 } 291 virtual void RegisterJITEventListener(JITEventListener *L); 292 virtual void UnregisterJITEventListener(JITEventListener *L); 293 294 // If successful, these function will implicitly finalize all loaded objects. 295 // To get a function address within MCJIT without causing a finalize, use 296 // getSymbolAddress. 297 virtual uint64_t getGlobalValueAddress(const std::string &Name); 298 virtual uint64_t getFunctionAddress(const std::string &Name); 299 300 /// @} 301 /// @name (Private) Registration Interfaces 302 /// @{ 303 Register()304 static void Register() { 305 MCJITCtor = createJIT; 306 } 307 308 static ExecutionEngine *createJIT(Module *M, 309 std::string *ErrorStr, 310 RTDyldMemoryManager *MemMgr, 311 bool GVsWithCode, 312 TargetMachine *TM); 313 314 // @} 315 316 // This is not directly exposed via the ExecutionEngine API, but it is 317 // used by the LinkingMemoryManager. 318 uint64_t getSymbolAddress(const std::string &Name, 319 bool CheckFunctionsOnly); 320 321 protected: 322 /// emitObject -- Generate a JITed object in memory from the specified module 323 /// Currently, MCJIT only supports a single module and the module passed to 324 /// this function call is expected to be the contained module. The module 325 /// is passed as a parameter here to prepare for multiple module support in 326 /// the future. 327 ObjectBufferStream* emitObject(Module *M); 328 329 void NotifyObjectEmitted(const ObjectImage& Obj); 330 void NotifyFreeingObject(const ObjectImage& Obj); 331 332 uint64_t getExistingSymbolAddress(const std::string &Name); 333 Module *findModuleForSymbol(const std::string &Name, 334 bool CheckFunctionsOnly); 335 }; 336 337 } // End llvm namespace 338 339 #endif 340