summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/interception
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/interception')
-rw-r--r--compiler-rt/lib/interception/interception_linux.cc6
-rw-r--r--compiler-rt/lib/interception/interception_linux.h14
-rw-r--r--compiler-rt/lib/interception/tests/interception_linux_test.cc11
3 files changed, 27 insertions, 4 deletions
diff --git a/compiler-rt/lib/interception/interception_linux.cc b/compiler-rt/lib/interception/interception_linux.cc
index 64d04d8df51..d019d482d6d 100644
--- a/compiler-rt/lib/interception/interception_linux.cc
+++ b/compiler-rt/lib/interception/interception_linux.cc
@@ -33,6 +33,12 @@ static int StrCmp(const char *s1, const char *s2) {
}
#endif
+bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
+ uptr real, uptr wrapper) {
+ *func_addr = (uptr)GetFuncAddr(func_name);
+ return real == wrapper;
+}
+
void *GetFuncAddr(const char *name) {
#if SANITIZER_NETBSD
// FIXME: Find a better way to handle renames
diff --git a/compiler-rt/lib/interception/interception_linux.h b/compiler-rt/lib/interception/interception_linux.h
index 0acb4e80b8c..4c60bd88090 100644
--- a/compiler-rt/lib/interception/interception_linux.h
+++ b/compiler-rt/lib/interception/interception_linux.h
@@ -22,18 +22,24 @@
#define INTERCEPTION_LINUX_H
namespace __interception {
+// returns true if a function with the given name was found.
+bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
+ uptr real, uptr wrapper);
void *GetFuncAddr(const char *name);
void *GetFuncAddrVer(const char *name, const char *ver);
} // namespace __interception
#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \
- (REAL(func) = (FUNC_TYPE(func)) ::__interception::GetFuncAddr(#func))
+ ::__interception::GetRealFunctionAddress( \
+ #func, (::__interception::uptr *)&__interception::PTR_TO_REAL(func), \
+ (::__interception::uptr) & (func), \
+ (::__interception::uptr) & WRAP(func))
// Android, Solaris and OpenBSD do not have dlvsym
#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
-#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
- (REAL(func) = \
- (FUNC_TYPE(func)) ::__interception::GetFuncAddrVer(#func, symver))
+#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
+ (::__interception::real_##func = (func##_type)( \
+ unsigned long)::__interception::GetFuncAddrVer(#func, symver))
#else
#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
diff --git a/compiler-rt/lib/interception/tests/interception_linux_test.cc b/compiler-rt/lib/interception/tests/interception_linux_test.cc
index 3aade45ebcd..5a1ca6ecbf5 100644
--- a/compiler-rt/lib/interception/tests/interception_linux_test.cc
+++ b/compiler-rt/lib/interception/tests/interception_linux_test.cc
@@ -33,6 +33,17 @@ INTERCEPTOR(int, isdigit, int d) {
namespace __interception {
+TEST(Interception, GetRealFunctionAddress) {
+ uptr malloc_address = 0;
+ EXPECT_TRUE(GetRealFunctionAddress("malloc", &malloc_address, 0, 0));
+ EXPECT_NE(0U, malloc_address);
+
+ uptr dummy_address = 0;
+ EXPECT_TRUE(
+ GetRealFunctionAddress("dummy_doesnt_exist__", &dummy_address, 0, 0));
+ EXPECT_EQ(0U, dummy_address);
+}
+
TEST(Interception, GetFuncAddr) {
EXPECT_NE(GetFuncAddr("malloc"), nullptr);
EXPECT_EQ(GetFuncAddr("does_not_exist"), nullptr);
OpenPOWER on IntegriCloud