+uint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) {
+ Mangler Mang(TM->getDataLayout());
+ SmallString<128> FullName;
+ Mang.getNameWithPrefix(FullName, Name);
+ return Dyld.getSymbolLoadAddress(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 NULL;
+}
+
+uint64_t MCJIT::getSymbolAddress(const std::string &Name,
+ bool CheckFunctionsOnly)
+{
+ MutexGuard locked(lock);
+
+ // First, check to see if we already have this symbol.
+ uint64_t Addr = getExistingSymbolAddress(Name);
+ if (Addr)
+ return Addr;
+
+ SmallVector<object::Archive*, 2>::iterator I, E;
+ for (I = Archives.begin(), E = Archives.end(); I != E; ++I) {
+ object::Archive *A = *I;
+ // Look for our symbols in each Archive
+ object::Archive::child_iterator ChildIt = A->findSym(Name);
+ if (ChildIt != A->child_end()) {
+ OwningPtr<object::Binary> ChildBin;
+ // FIXME: Support nested archives?
+ if (!ChildIt->getAsBinary(ChildBin) && ChildBin->isObject()) {
+ object::ObjectFile *OF = reinterpret_cast<object::ObjectFile *>(
+ ChildBin.take());
+ // This causes the object file to be loaded.
+ addObjectFile(OF);
+ // The address should be here now.
+ Addr = getExistingSymbolAddress(Name);
+ if (Addr)
+ return Addr;
+ }
+ }
+ }
+
+ // If it hasn't already been generated, see if it's in one of our modules.
+ Module *M = findModuleForSymbol(Name, CheckFunctionsOnly);
+ if (!M)
+ return 0;
+
+ generateCodeForModule(M);
+
+ // Check the RuntimeDyld table again, it should be there now.
+ return getExistingSymbolAddress(Name);
+}