LLVM API Documentation

MCJIT.cpp
Go to the documentation of this file.
00001 //===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "MCJIT.h"
00011 #include "llvm/ExecutionEngine/GenericValue.h"
00012 #include "llvm/ExecutionEngine/JITEventListener.h"
00013 #include "llvm/ExecutionEngine/JITMemoryManager.h"
00014 #include "llvm/ExecutionEngine/MCJIT.h"
00015 #include "llvm/ExecutionEngine/ObjectBuffer.h"
00016 #include "llvm/ExecutionEngine/ObjectImage.h"
00017 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
00018 #include "llvm/IR/DataLayout.h"
00019 #include "llvm/IR/DerivedTypes.h"
00020 #include "llvm/IR/Function.h"
00021 #include "llvm/IR/Mangler.h"
00022 #include "llvm/IR/Module.h"
00023 #include "llvm/MC/MCAsmInfo.h"
00024 #include "llvm/Object/Archive.h"
00025 #include "llvm/PassManager.h"
00026 #include "llvm/Support/DynamicLibrary.h"
00027 #include "llvm/Support/ErrorHandling.h"
00028 #include "llvm/Support/MemoryBuffer.h"
00029 #include "llvm/Support/MutexGuard.h"
00030 #include "llvm/Target/TargetLowering.h"
00031 #include "llvm/Target/TargetSubtargetInfo.h"
00032 
00033 using namespace llvm;
00034 
00035 namespace {
00036 
00037 static struct RegisterJIT {
00038   RegisterJIT() { MCJIT::Register(); }
00039 } JITRegistrator;
00040 
00041 }
00042 
00043 extern "C" void LLVMLinkInMCJIT() {
00044 }
00045 
00046 ExecutionEngine *MCJIT::createJIT(std::unique_ptr<Module> M,
00047                                   std::string *ErrorStr,
00048                                   RTDyldMemoryManager *MemMgr,
00049                                   TargetMachine *TM) {
00050   // Try to register the program as a source of symbols to resolve against.
00051   //
00052   // FIXME: Don't do this here.
00053   sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
00054 
00055   return new MCJIT(std::move(M), TM,
00056                    MemMgr ? MemMgr : new SectionMemoryManager());
00057 }
00058 
00059 MCJIT::MCJIT(std::unique_ptr<Module> M, TargetMachine *tm,
00060              RTDyldMemoryManager *MM)
00061     : ExecutionEngine(std::move(M)), TM(tm), Ctx(nullptr), MemMgr(this, MM),
00062       Dyld(&MemMgr), ObjCache(nullptr) {
00063   // FIXME: We are managing our modules, so we do not want the base class
00064   // ExecutionEngine to manage them as well. To avoid double destruction
00065   // of the first (and only) module added in ExecutionEngine constructor
00066   // we remove it from EE and will destruct it ourselves.
00067   //
00068   // It may make sense to move our module manager (based on SmallStPtr) back
00069   // into EE if the JIT and Interpreter can live with it.
00070   // If so, additional functions: addModule, removeModule, FindFunctionNamed,
00071   // runStaticConstructorsDestructors could be moved back to EE as well.
00072   //
00073   std::unique_ptr<Module> First = std::move(Modules[0]);
00074   Modules.clear();
00075 
00076   OwnedModules.addModule(std::move(First));
00077   setDataLayout(TM->getSubtargetImpl()->getDataLayout());
00078 }
00079 
00080 MCJIT::~MCJIT() {
00081   MutexGuard locked(lock);
00082 
00083   Dyld.deregisterEHFrames();
00084 
00085   LoadedObjectList::iterator it, end;
00086   for (it = LoadedObjects.begin(), end = LoadedObjects.end(); it != end; ++it) {
00087     ObjectImage *Obj = *it;
00088     if (Obj) {
00089       NotifyFreeingObject(*Obj);
00090       delete Obj;
00091     }
00092   }
00093   LoadedObjects.clear();
00094 
00095   Archives.clear();
00096 
00097   delete TM;
00098 }
00099 
00100 void MCJIT::addModule(std::unique_ptr<Module> M) {
00101   MutexGuard locked(lock);
00102   OwnedModules.addModule(std::move(M));
00103 }
00104 
00105 bool MCJIT::removeModule(Module *M) {
00106   MutexGuard locked(lock);
00107   return OwnedModules.removeModule(M);
00108 }
00109 
00110 
00111 
00112 void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
00113   ObjectImage *LoadedObject = Dyld.loadObject(std::move(Obj));
00114   if (!LoadedObject || Dyld.hasError())
00115     report_fatal_error(Dyld.getErrorString());
00116 
00117   LoadedObjects.push_back(LoadedObject);
00118 
00119   NotifyObjectEmitted(*LoadedObject);
00120 }
00121 
00122 void MCJIT::addArchive(object::OwningBinary<object::Archive> A) {
00123   Archives.push_back(std::move(A));
00124 }
00125 
00126 
00127 void MCJIT::setObjectCache(ObjectCache* NewCache) {
00128   MutexGuard locked(lock);
00129   ObjCache = NewCache;
00130 }
00131 
00132 ObjectBufferStream* MCJIT::emitObject(Module *M) {
00133   MutexGuard locked(lock);
00134 
00135   // This must be a module which has already been added but not loaded to this
00136   // MCJIT instance, since these conditions are tested by our caller,
00137   // generateCodeForModule.
00138 
00139   PassManager PM;
00140 
00141   M->setDataLayout(TM->getSubtargetImpl()->getDataLayout());
00142   PM.add(new DataLayoutPass(M));
00143 
00144   // The RuntimeDyld will take ownership of this shortly
00145   std::unique_ptr<ObjectBufferStream> CompiledObject(new ObjectBufferStream());
00146 
00147   // Turn the machine code intermediate representation into bytes in memory
00148   // that may be executed.
00149   if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(),
00150                             !getVerifyModules())) {
00151     report_fatal_error("Target does not support MC emission!");
00152   }
00153 
00154   // Initialize passes.
00155   PM.run(*M);
00156   // Flush the output buffer to get the generated code into memory
00157   CompiledObject->flush();
00158 
00159   // If we have an object cache, tell it about the new object.
00160   // Note that we're using the compiled image, not the loaded image (as below).
00161   if (ObjCache) {
00162     // MemoryBuffer is a thin wrapper around the actual memory, so it's OK
00163     // to create a temporary object here and delete it after the call.
00164     MemoryBufferRef MB = CompiledObject->getMemBuffer();
00165     ObjCache->notifyObjectCompiled(M, MB);
00166   }
00167 
00168   return CompiledObject.release();
00169 }
00170 
00171 void MCJIT::generateCodeForModule(Module *M) {
00172   // Get a thread lock to make sure we aren't trying to load multiple times
00173   MutexGuard locked(lock);
00174 
00175   // This must be a module which has already been added to this MCJIT instance.
00176   assert(OwnedModules.ownsModule(M) &&
00177          "MCJIT::generateCodeForModule: Unknown module.");
00178 
00179   // Re-compilation is not supported
00180   if (OwnedModules.hasModuleBeenLoaded(M))
00181     return;
00182 
00183   std::unique_ptr<ObjectBuffer> ObjectToLoad;
00184   // Try to load the pre-compiled object from cache if possible
00185   if (ObjCache) {
00186     std::unique_ptr<MemoryBuffer> PreCompiledObject(ObjCache->getObject(M));
00187     if (PreCompiledObject.get())
00188       ObjectToLoad.reset(new ObjectBuffer(PreCompiledObject.release()));
00189   }
00190 
00191   // If the cache did not contain a suitable object, compile the object
00192   if (!ObjectToLoad) {
00193     ObjectToLoad.reset(emitObject(M));
00194     assert(ObjectToLoad.get() && "Compilation did not produce an object.");
00195   }
00196 
00197   // Load the object into the dynamic linker.
00198   // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
00199   ObjectImage *LoadedObject = Dyld.loadObject(ObjectToLoad.release());
00200   LoadedObjects.push_back(LoadedObject);
00201   if (!LoadedObject)
00202     report_fatal_error(Dyld.getErrorString());
00203 
00204   // FIXME: Make this optional, maybe even move it to a JIT event listener
00205   LoadedObject->registerWithDebugger();
00206 
00207   NotifyObjectEmitted(*LoadedObject);
00208 
00209   OwnedModules.markModuleAsLoaded(M);
00210 }
00211 
00212 void MCJIT::finalizeLoadedModules() {
00213   MutexGuard locked(lock);
00214 
00215   // Resolve any outstanding relocations.
00216   Dyld.resolveRelocations();
00217 
00218   OwnedModules.markAllLoadedModulesAsFinalized();
00219 
00220   // Register EH frame data for any module we own which has been loaded
00221   Dyld.registerEHFrames();
00222 
00223   // Set page permissions.
00224   MemMgr.finalizeMemory();
00225 }
00226 
00227 // FIXME: Rename this.
00228 void MCJIT::finalizeObject() {
00229   MutexGuard locked(lock);
00230 
00231   for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
00232                               E = OwnedModules.end_added();
00233        I != E; ++I) {
00234     Module *M = *I;
00235     generateCodeForModule(M);
00236   }
00237 
00238   finalizeLoadedModules();
00239 }
00240 
00241 void MCJIT::finalizeModule(Module *M) {
00242   MutexGuard locked(lock);
00243 
00244   // This must be a module which has already been added to this MCJIT instance.
00245   assert(OwnedModules.ownsModule(M) && "MCJIT::finalizeModule: Unknown module.");
00246 
00247   // If the module hasn't been compiled, just do that.
00248   if (!OwnedModules.hasModuleBeenLoaded(M))
00249     generateCodeForModule(M);
00250 
00251   finalizeLoadedModules();
00252 }
00253 
00254 void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
00255   report_fatal_error("not yet implemented");
00256 }
00257 
00258 uint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) {
00259   Mangler Mang(TM->getSubtargetImpl()->getDataLayout());
00260   SmallString<128> FullName;
00261   Mang.getNameWithPrefix(FullName, Name);
00262   return Dyld.getSymbolLoadAddress(FullName);
00263 }
00264 
00265 Module *MCJIT::findModuleForSymbol(const std::string &Name,
00266                                    bool CheckFunctionsOnly) {
00267   MutexGuard locked(lock);
00268 
00269   // If it hasn't already been generated, see if it's in one of our modules.
00270   for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
00271                               E = OwnedModules.end_added();
00272        I != E; ++I) {
00273     Module *M = *I;
00274     Function *F = M->getFunction(Name);
00275     if (F && !F->isDeclaration())
00276       return M;
00277     if (!CheckFunctionsOnly) {
00278       GlobalVariable *G = M->getGlobalVariable(Name);
00279       if (G && !G->isDeclaration())
00280         return M;
00281       // FIXME: Do we need to worry about global aliases?
00282     }
00283   }
00284   // We didn't find the symbol in any of our modules.
00285   return nullptr;
00286 }
00287 
00288 uint64_t MCJIT::getSymbolAddress(const std::string &Name,
00289                                  bool CheckFunctionsOnly)
00290 {
00291   MutexGuard locked(lock);
00292 
00293   // First, check to see if we already have this symbol.
00294   uint64_t Addr = getExistingSymbolAddress(Name);
00295   if (Addr)
00296     return Addr;
00297 
00298   for (object::OwningBinary<object::Archive> &OB : Archives) {
00299     object::Archive *A = OB.getBinary().get();
00300     // Look for our symbols in each Archive
00301     object::Archive::child_iterator ChildIt = A->findSym(Name);
00302     if (ChildIt != A->child_end()) {
00303       // FIXME: Support nested archives?
00304       ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
00305           ChildIt->getAsBinary();
00306       if (ChildBinOrErr.getError())
00307         continue;
00308       std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
00309       if (ChildBin->isObject()) {
00310         std::unique_ptr<object::ObjectFile> OF(
00311             static_cast<object::ObjectFile *>(ChildBin.release()));
00312         // This causes the object file to be loaded.
00313         addObjectFile(std::move(OF));
00314         // The address should be here now.
00315         Addr = getExistingSymbolAddress(Name);
00316         if (Addr)
00317           return Addr;
00318       }
00319     }
00320   }
00321 
00322   // If it hasn't already been generated, see if it's in one of our modules.
00323   Module *M = findModuleForSymbol(Name, CheckFunctionsOnly);
00324   if (M) {
00325     generateCodeForModule(M);
00326 
00327     // Check the RuntimeDyld table again, it should be there now.
00328     return getExistingSymbolAddress(Name);
00329   }
00330 
00331   // If a LazyFunctionCreator is installed, use it to get/create the function.
00332   // FIXME: Should we instead have a LazySymbolCreator callback?
00333   if (LazyFunctionCreator)
00334     Addr = (uint64_t)LazyFunctionCreator(Name);
00335 
00336   return Addr;
00337 }
00338 
00339 uint64_t MCJIT::getGlobalValueAddress(const std::string &Name) {
00340   MutexGuard locked(lock);
00341   uint64_t Result = getSymbolAddress(Name, false);
00342   if (Result != 0)
00343     finalizeLoadedModules();
00344   return Result;
00345 }
00346 
00347 uint64_t MCJIT::getFunctionAddress(const std::string &Name) {
00348   MutexGuard locked(lock);
00349   uint64_t Result = getSymbolAddress(Name, true);
00350   if (Result != 0)
00351     finalizeLoadedModules();
00352   return Result;
00353 }
00354 
00355 // Deprecated.  Use getFunctionAddress instead.
00356 void *MCJIT::getPointerToFunction(Function *F) {
00357   MutexGuard locked(lock);
00358 
00359   if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
00360     bool AbortOnFailure = !F->hasExternalWeakLinkage();
00361     void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure);
00362     addGlobalMapping(F, Addr);
00363     return Addr;
00364   }
00365 
00366   Module *M = F->getParent();
00367   bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M);
00368 
00369   // Make sure the relevant module has been compiled and loaded.
00370   if (HasBeenAddedButNotLoaded)
00371     generateCodeForModule(M);
00372   else if (!OwnedModules.hasModuleBeenLoaded(M))
00373     // If this function doesn't belong to one of our modules, we're done.
00374     return nullptr;
00375 
00376   // FIXME: Should the Dyld be retaining module information? Probably not.
00377   //
00378   // This is the accessor for the target address, so make sure to check the
00379   // load address of the symbol, not the local address.
00380   Mangler Mang(TM->getSubtargetImpl()->getDataLayout());
00381   SmallString<128> Name;
00382   TM->getNameWithPrefix(Name, F, Mang);
00383   return (void*)Dyld.getSymbolLoadAddress(Name);
00384 }
00385 
00386 void *MCJIT::recompileAndRelinkFunction(Function *F) {
00387   report_fatal_error("not yet implemented");
00388 }
00389 
00390 void MCJIT::freeMachineCodeForFunction(Function *F) {
00391   report_fatal_error("not yet implemented");
00392 }
00393 
00394 void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
00395     bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
00396   for (; I != E; ++I) {
00397     ExecutionEngine::runStaticConstructorsDestructors(**I, isDtors);
00398   }
00399 }
00400 
00401 void MCJIT::runStaticConstructorsDestructors(bool isDtors) {
00402   // Execute global ctors/dtors for each module in the program.
00403   runStaticConstructorsDestructorsInModulePtrSet(
00404       isDtors, OwnedModules.begin_added(), OwnedModules.end_added());
00405   runStaticConstructorsDestructorsInModulePtrSet(
00406       isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded());
00407   runStaticConstructorsDestructorsInModulePtrSet(
00408       isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized());
00409 }
00410 
00411 Function *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName,
00412                                                  ModulePtrSet::iterator I,
00413                                                  ModulePtrSet::iterator E) {
00414   for (; I != E; ++I) {
00415     if (Function *F = (*I)->getFunction(FnName))
00416       return F;
00417   }
00418   return nullptr;
00419 }
00420 
00421 Function *MCJIT::FindFunctionNamed(const char *FnName) {
00422   Function *F = FindFunctionNamedInModulePtrSet(
00423       FnName, OwnedModules.begin_added(), OwnedModules.end_added());
00424   if (!F)
00425     F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(),
00426                                         OwnedModules.end_loaded());
00427   if (!F)
00428     F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(),
00429                                         OwnedModules.end_finalized());
00430   return F;
00431 }
00432 
00433 GenericValue MCJIT::runFunction(Function *F,
00434                                 const std::vector<GenericValue> &ArgValues) {
00435   assert(F && "Function *F was null at entry to run()");
00436 
00437   void *FPtr = getPointerToFunction(F);
00438   assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
00439   FunctionType *FTy = F->getFunctionType();
00440   Type *RetTy = FTy->getReturnType();
00441 
00442   assert((FTy->getNumParams() == ArgValues.size() ||
00443           (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
00444          "Wrong number of arguments passed into function!");
00445   assert(FTy->getNumParams() == ArgValues.size() &&
00446          "This doesn't support passing arguments through varargs (yet)!");
00447 
00448   // Handle some common cases first.  These cases correspond to common `main'
00449   // prototypes.
00450   if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
00451     switch (ArgValues.size()) {
00452     case 3:
00453       if (FTy->getParamType(0)->isIntegerTy(32) &&
00454           FTy->getParamType(1)->isPointerTy() &&
00455           FTy->getParamType(2)->isPointerTy()) {
00456         int (*PF)(int, char **, const char **) =
00457           (int(*)(int, char **, const char **))(intptr_t)FPtr;
00458 
00459         // Call the function.
00460         GenericValue rv;
00461         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
00462                                  (char **)GVTOP(ArgValues[1]),
00463                                  (const char **)GVTOP(ArgValues[2])));
00464         return rv;
00465       }
00466       break;
00467     case 2:
00468       if (FTy->getParamType(0)->isIntegerTy(32) &&
00469           FTy->getParamType(1)->isPointerTy()) {
00470         int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
00471 
00472         // Call the function.
00473         GenericValue rv;
00474         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
00475                                  (char **)GVTOP(ArgValues[1])));
00476         return rv;
00477       }
00478       break;
00479     case 1:
00480       if (FTy->getNumParams() == 1 &&
00481           FTy->getParamType(0)->isIntegerTy(32)) {
00482         GenericValue rv;
00483         int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
00484         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
00485         return rv;
00486       }
00487       break;
00488     }
00489   }
00490 
00491   // Handle cases where no arguments are passed first.
00492   if (ArgValues.empty()) {
00493     GenericValue rv;
00494     switch (RetTy->getTypeID()) {
00495     default: llvm_unreachable("Unknown return type for function call!");
00496     case Type::IntegerTyID: {
00497       unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
00498       if (BitWidth == 1)
00499         rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
00500       else if (BitWidth <= 8)
00501         rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
00502       else if (BitWidth <= 16)
00503         rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
00504       else if (BitWidth <= 32)
00505         rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
00506       else if (BitWidth <= 64)
00507         rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
00508       else
00509         llvm_unreachable("Integer types > 64 bits not supported");
00510       return rv;
00511     }
00512     case Type::VoidTyID:
00513       rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
00514       return rv;
00515     case Type::FloatTyID:
00516       rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
00517       return rv;
00518     case Type::DoubleTyID:
00519       rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
00520       return rv;
00521     case Type::X86_FP80TyID:
00522     case Type::FP128TyID:
00523     case Type::PPC_FP128TyID:
00524       llvm_unreachable("long double not supported yet");
00525     case Type::PointerTyID:
00526       return PTOGV(((void*(*)())(intptr_t)FPtr)());
00527     }
00528   }
00529 
00530   llvm_unreachable("Full-featured argument passing not supported yet!");
00531 }
00532 
00533 void *MCJIT::getPointerToNamedFunction(const std::string &Name,
00534                                        bool AbortOnFailure) {
00535   if (!isSymbolSearchingDisabled()) {
00536     void *ptr = MemMgr.getPointerToNamedFunction(Name, false);
00537     if (ptr)
00538       return ptr;
00539   }
00540 
00541   /// If a LazyFunctionCreator is installed, use it to get/create the function.
00542   if (LazyFunctionCreator)
00543     if (void *RP = LazyFunctionCreator(Name))
00544       return RP;
00545 
00546   if (AbortOnFailure) {
00547     report_fatal_error("Program used external function '"+Name+
00548                        "' which could not be resolved!");
00549   }
00550   return nullptr;
00551 }
00552 
00553 void MCJIT::RegisterJITEventListener(JITEventListener *L) {
00554   if (!L)
00555     return;
00556   MutexGuard locked(lock);
00557   EventListeners.push_back(L);
00558 }
00559 void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
00560   if (!L)
00561     return;
00562   MutexGuard locked(lock);
00563   SmallVector<JITEventListener*, 2>::reverse_iterator I=
00564       std::find(EventListeners.rbegin(), EventListeners.rend(), L);
00565   if (I != EventListeners.rend()) {
00566     std::swap(*I, EventListeners.back());
00567     EventListeners.pop_back();
00568   }
00569 }
00570 void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) {
00571   MutexGuard locked(lock);
00572   MemMgr.notifyObjectLoaded(this, &Obj);
00573   for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
00574     EventListeners[I]->NotifyObjectEmitted(Obj);
00575   }
00576 }
00577 void MCJIT::NotifyFreeingObject(const ObjectImage& Obj) {
00578   MutexGuard locked(lock);
00579   for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
00580     EventListeners[I]->NotifyFreeingObject(Obj);
00581   }
00582 }
00583 
00584 uint64_t LinkingMemoryManager::getSymbolAddress(const std::string &Name) {
00585   uint64_t Result = ParentEngine->getSymbolAddress(Name, false);
00586   // If the symbols wasn't found and it begins with an underscore, try again
00587   // without the underscore.
00588   if (!Result && Name[0] == '_')
00589     Result = ParentEngine->getSymbolAddress(Name.substr(1), false);
00590   if (Result)
00591     return Result;
00592   if (ParentEngine->isSymbolSearchingDisabled())
00593     return 0;
00594   return ClientMM->getSymbolAddress(Name);
00595 }