summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2014-09-20 17:44:56 +0000
committerLang Hames <lhames@gmail.com>2014-09-20 17:44:56 +0000
commitb7fbf593e6b045a448425c60f92c266502c8596f (patch)
treedb3315ba1ee6d8d0e16233fce0663be1db32439d /llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp
parent21130fbc04df970582e630c9e1a74b0cb0f57242 (diff)
downloadbcm5719-llvm-b7fbf593e6b045a448425c60f92c266502c8596f.tar.gz
bcm5719-llvm-b7fbf593e6b045a448425c60f92c266502c8596f.zip
[MCJIT] Make RTDyldMemoryManager::getSymbolAddress's behaviour more consistent.
This patch modifies RTDyldMemoryManager::getSymbolAddress(Name)'s behavior to make it consistent with how clients are using it: Name should be mangled, and getSymbolAddress should demangle it on the caller's behalf before looking the name up in the process. This patch also fixes the one client (MCJIT::getPointerToFunction) that had been passing unmangled names (by having it pass mangled names instead). Background: RTDyldMemoryManager::getSymbolAddress(Name) has always used a re-try mechanism when looking up symbol names in the current process. Prior to this patch getSymbolAddress first tried to look up 'Name' exactly as the user passed it in and then, if that failed, tried to demangle 'Name' and re-try the look up. The implication of this behavior is that getSymbolAddress expected to be called with unmangled names, and that handling mangled names was a fallback for convenience. This is inconsistent with how clients (particularly the RuntimeDyldImpl subclasses, but also MCJIT) usually use this API. Most clients pass in mangled names, and succeed only because of the fallback case. For clients passing in mangled names, getSymbolAddress's old behavior was actually dangerous, as it could cause unmangled names in the process to shadow mangled names being looked up. For example, consider: foo.c: int _x = 7; int x() { return _x; } foo.o: 000000000000000c D __x 0000000000000000 T _x If foo.c becomes part of the process (E.g. via dlopen("libfoo.dylib")) it will add symbols 'x' (the function) and '_x' (the variable) to the process. However jit clients looking for the function 'x' will be using the mangled function name '_x' (note how function 'x' appears in foo.o). When getSymbolAddress goes looking for '_x' it will find the variable instead, and return its address and in place of the function, leading to JIT'd code calling the variable and crashing (if we're lucky). By requiring that getSymbolAddress be called with mangled names, and demangling only when we're about to do a lookup in the process, the new behavior implemented in this patch should eliminate any chance of names being shadowed during lookup. There's no good way to test this at the moment: This issue only arrises when looking up process symbols (not JIT'd symbols). Any test case would have to generate a platform-appropriate dylib to pass to llvm-rtdyld, and I'm not aware of any in-tree tool for doing this in a portable way. llvm-svn: 218187
Diffstat (limited to 'llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp')
-rw-r--r--llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp21
1 files changed, 11 insertions, 10 deletions
diff --git a/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp b/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp
index 1646937e816..9cbcd2fa814 100644
--- a/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp
+++ b/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp
@@ -253,19 +253,20 @@ 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.
+ if (void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr))
+ return (uint64_t)Ptr;
}
void *RTDyldMemoryManager::getPointerToNamedFunction(const std::string &Name,
OpenPOWER on IntegriCloud