+// FIXME: Rename this.
+void MCJIT::finalizeObject() {
+ MutexGuard locked(lock);
+
+ // Generate code for module is going to move objects out of the 'added' list,
+ // so we need to copy that out before using it:
+ SmallVector<Module*, 16> ModsToAdd;
+ for (auto M : OwnedModules.added())
+ ModsToAdd.push_back(M);
+
+ for (auto M : ModsToAdd)
+ generateCodeForModule(M);
+
+ finalizeLoadedModules();
+}
+
+void MCJIT::finalizeModule(Module *M) {
+ MutexGuard locked(lock);
+
+ // This must be a module which has already been added to this MCJIT instance.
+ assert(OwnedModules.ownsModule(M) && "MCJIT::finalizeModule: Unknown module.");
+
+ // If the module hasn't been compiled, just do that.
+ if (!OwnedModules.hasModuleBeenLoaded(M))
+ generateCodeForModule(M);
+
+ finalizeLoadedModules();
+}
+
+RuntimeDyld::SymbolInfo MCJIT::findExistingSymbol(const std::string &Name) {
+ SmallString<128> FullName;
+ Mangler::getNameWithPrefix(FullName, Name, getDataLayout());
+ return Dyld.getSymbol(FullName);
+}
+
+Module *MCJIT::findModuleForSymbol(const std::string &Name,
+ bool CheckFunctionsOnly) {
+ MutexGuard locked(lock);
+
+ // If it hasn't already been generated, see if it's in one of our modules.
+ for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
+ E = OwnedModules.end_added();
+ I != E; ++I) {
+ Module *M = *I;
+ Function *F = M->getFunction(Name);
+ if (F && !F->isDeclaration())
+ return M;
+ if (!CheckFunctionsOnly) {
+ GlobalVariable *G = M->getGlobalVariable(Name);
+ if (G && !G->isDeclaration())
+ return M;
+ // FIXME: Do we need to worry about global aliases?
+ }
+ }
+ // We didn't find the symbol in any of our modules.
+ return nullptr;
+}
+
+uint64_t MCJIT::getSymbolAddress(const std::string &Name,
+ bool CheckFunctionsOnly) {
+ return findSymbol(Name, CheckFunctionsOnly).getAddress();
+}
+
+RuntimeDyld::SymbolInfo MCJIT::findSymbol(const std::string &Name,
+ bool CheckFunctionsOnly) {
+ MutexGuard locked(lock);
+
+ // First, check to see if we already have this symbol.
+ if (auto Sym = findExistingSymbol(Name))
+ return Sym;
+
+ for (object::OwningBinary<object::Archive> &OB : Archives) {
+ object::Archive *A = OB.getBinary();
+ // Look for our symbols in each Archive
+ object::Archive::child_iterator ChildIt = A->findSym(Name);
+ if (ChildIt != A->child_end()) {
+ // FIXME: Support nested archives?
+ ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
+ ChildIt->getAsBinary();
+ if (ChildBinOrErr.getError())
+ continue;
+ std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
+ if (ChildBin->isObject()) {
+ std::unique_ptr<object::ObjectFile> OF(
+ static_cast<object::ObjectFile *>(ChildBin.release()));
+ // This causes the object file to be loaded.
+ addObjectFile(std::move(OF));
+ // The address should be here now.
+ if (auto Sym = findExistingSymbol(Name))
+ return Sym;
+ }
+ }
+ }
+
+ // If it hasn't already been generated, see if it's in one of our modules.
+ Module *M = findModuleForSymbol(Name, CheckFunctionsOnly);
+ if (M) {
+ generateCodeForModule(M);
+
+ // Check the RuntimeDyld table again, it should be there now.
+ return findExistingSymbol(Name);
+ }
+
+ // If a LazyFunctionCreator is installed, use it to get/create the function.
+ // FIXME: Should we instead have a LazySymbolCreator callback?
+ if (LazyFunctionCreator) {
+ auto Addr = static_cast<uint64_t>(
+ reinterpret_cast<uintptr_t>(LazyFunctionCreator(Name)));
+ return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
+ }
+
+ return nullptr;