diff options
Diffstat (limited to 'contrib/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp')
-rw-r--r-- | contrib/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/contrib/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp b/contrib/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp index 1646937..2a5e4f8 100644 --- a/contrib/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp @@ -13,6 +13,7 @@ #include "llvm/Config/config.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" #include <cstdlib> @@ -210,7 +211,13 @@ ARM_MATH_IMPORTS(ARM_MATH_DECL) #undef ARM_MATH_DECL #endif -uint64_t RTDyldMemoryManager::getSymbolAddress(const std::string &Name) { +#if defined(__linux__) && defined(__GLIBC__) && \ + (defined(__i386__) || defined(__x86_64__)) +extern "C" LLVM_ATTRIBUTE_WEAK void __morestack(); +#endif + +uint64_t +RTDyldMemoryManager::getSymbolAddressInProcess(const std::string &Name) { // This implementation assumes that the host program is the target. // Clients generating code for a remote target should implement their own // memory manager. @@ -232,6 +239,12 @@ uint64_t RTDyldMemoryManager::getSymbolAddress(const std::string &Name) { if (Name == "lstat64") return (uint64_t)&lstat64; if (Name == "atexit") return (uint64_t)&atexit; if (Name == "mknod") return (uint64_t)&mknod; + +#if defined(__i386__) || defined(__x86_64__) + // __morestack lives in libgcc, a static library. + if (&__morestack && Name == "__morestack") + return (uint64_t)&__morestack; +#endif #endif // __linux__ && __GLIBC__ // See ARM_MATH_IMPORTS definition for explanation @@ -253,19 +266,19 @@ uint64_t RTDyldMemoryManager::getSymbolAddress(const std::string &Name) { // is called before ExecutionEngine::runFunctionAsMain() is called. if (Name == "__main") return (uint64_t)&jit_noop; + // Try to demangle Name before looking it up in the process, otherwise symbol + // '_<Name>' (if present) will shadow '<Name>', and there will be no way to + // refer to the latter. + const char *NameStr = Name.c_str(); - void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); - if (Ptr) - return (uint64_t)Ptr; - - // If it wasn't found and if it starts with an underscore ('_') character, - // try again without the underscore. - if (NameStr[0] == '_') { - Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1); - if (Ptr) + + if (NameStr[0] == '_') + if (void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr + 1)) return (uint64_t)Ptr; - } - return 0; + + // If we Name did not require demangling, or we failed to find the demangled + // name, try again without demangling. + return (uint64_t)sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); } void *RTDyldMemoryManager::getPointerToNamedFunction(const std::string &Name, |