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