summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-11-18 10:33:15 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-11-18 10:33:15 +0000
commit7555f5ed1f0b76ef3ff0b0550f1d62a2203c69d3 (patch)
tree3ec95fa5c3424c83e4e5fcc6ac2405a9533c58a1
parent62cec44ca45121206d611722f98b109ecbd6e11d (diff)
downloadbcm5719-llvm-7555f5ed1f0b76ef3ff0b0550f1d62a2203c69d3.tar.gz
bcm5719-llvm-7555f5ed1f0b76ef3ff0b0550f1d62a2203c69d3.zip
[msan] Remove MSanDR and supporting code.
MSanDR is a dynamic instrumentation tool that can instrument the code (prebuilt libraries and such) that could not be instrumented at compile time. This code is unused (to the best of our knowledge) and unmaintained, and starting to bit-rot. llvm-svn: 222232
-rw-r--r--compiler-rt/lib/CMakeLists.txt1
-rw-r--r--compiler-rt/lib/asan/asan_interceptors.h2
-rw-r--r--compiler-rt/lib/asan/asan_malloc_win.cc2
-rw-r--r--compiler-rt/lib/asan/asan_new_delete.cc2
-rw-r--r--compiler-rt/lib/asan/asan_win_dll_thunk.cc2
-rw-r--r--compiler-rt/lib/lsan/lsan_interceptors.cc2
-rw-r--r--compiler-rt/lib/msan/msan.cc54
-rw-r--r--compiler-rt/lib/msan/msan.h3
-rw-r--r--compiler-rt/lib/msan/msan_interceptors.cc46
-rw-r--r--compiler-rt/lib/msan/msan_interface_internal.h19
-rw-r--r--compiler-rt/lib/msan/msan_new_delete.cc2
-rw-r--r--compiler-rt/lib/msan/msan_thread.cc2
-rw-r--r--compiler-rt/lib/msan/tests/msan_loadable.cc18
-rw-r--r--compiler-rt/lib/msan/tests/msan_test.cc62
-rw-r--r--compiler-rt/lib/msandr/CMakeLists.txt26
-rw-r--r--compiler-rt/lib/msandr/README.txt40
-rw-r--r--compiler-rt/lib/msandr/msandr.cc900
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common.h17
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc18
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_interception.h25
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc12
-rw-r--r--compiler-rt/test/msan/wrap_indirect_calls.cc64
-rw-r--r--compiler-rt/test/msan/wrap_indirect_calls/caller.cc51
-rw-r--r--compiler-rt/test/msan/wrap_indirect_calls/lit.local.cfg3
-rw-r--r--compiler-rt/test/msan/wrap_indirect_calls/one.cc3
-rw-r--r--compiler-rt/test/msan/wrap_indirect_calls/two.cc11
-rw-r--r--compiler-rt/test/msan/wrap_indirect_calls/wrapper.cc11
-rw-r--r--compiler-rt/test/msan/wrap_indirect_calls2.cc42
-rw-r--r--compiler-rt/test/msan/wrap_indirect_calls_in_rtl.cc77
29 files changed, 37 insertions, 1480 deletions
diff --git a/compiler-rt/lib/CMakeLists.txt b/compiler-rt/lib/CMakeLists.txt
index 934c5b7f854..6929e682fac 100644
--- a/compiler-rt/lib/CMakeLists.txt
+++ b/compiler-rt/lib/CMakeLists.txt
@@ -25,7 +25,6 @@ endif()
if(COMPILER_RT_HAS_MSAN)
add_subdirectory(msan)
- add_subdirectory(msandr)
endif()
if(COMPILER_RT_HAS_PROFILE)
diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h
index 55460c29b54..ee3b82aa7ef 100644
--- a/compiler-rt/lib/asan/asan_interceptors.h
+++ b/compiler-rt/lib/asan/asan_interceptors.h
@@ -15,7 +15,7 @@
#define ASAN_INTERCEPTORS_H
#include "asan_internal.h"
-#include "sanitizer_common/sanitizer_interception.h"
+#include "interception/interception.h"
#include "sanitizer_common/sanitizer_platform_interceptors.h"
// Use macro to describe if specific function should be
diff --git a/compiler-rt/lib/asan/asan_malloc_win.cc b/compiler-rt/lib/asan/asan_malloc_win.cc
index 8c1c448f229..c99e3123495 100644
--- a/compiler-rt/lib/asan/asan_malloc_win.cc
+++ b/compiler-rt/lib/asan/asan_malloc_win.cc
@@ -19,7 +19,7 @@
#include "asan_interceptors.h"
#include "asan_internal.h"
#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_interception.h"
+#include "interception/interception.h"
#include <stddef.h>
diff --git a/compiler-rt/lib/asan/asan_new_delete.cc b/compiler-rt/lib/asan/asan_new_delete.cc
index 242760275fe..e48bdaf03dd 100644
--- a/compiler-rt/lib/asan/asan_new_delete.cc
+++ b/compiler-rt/lib/asan/asan_new_delete.cc
@@ -16,7 +16,7 @@
#include "asan_internal.h"
#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_interception.h"
+#include "interception/interception.h"
#include <stddef.h>
diff --git a/compiler-rt/lib/asan/asan_win_dll_thunk.cc b/compiler-rt/lib/asan/asan_win_dll_thunk.cc
index dff6e181a53..b38a2d16087 100644
--- a/compiler-rt/lib/asan/asan_win_dll_thunk.cc
+++ b/compiler-rt/lib/asan/asan_win_dll_thunk.cc
@@ -21,7 +21,7 @@
// simplifies the build procedure.
#ifdef ASAN_DLL_THUNK
#include "asan_init_version.h"
-#include "sanitizer_common/sanitizer_interception.h"
+#include "interception/interception.h"
// ---------- Function interception helper functions and macros ----------- {{{1
extern "C" {
diff --git a/compiler-rt/lib/lsan/lsan_interceptors.cc b/compiler-rt/lib/lsan/lsan_interceptors.cc
index 484f578c0a7..b01bbf8e4bc 100644
--- a/compiler-rt/lib/lsan/lsan_interceptors.cc
+++ b/compiler-rt/lib/lsan/lsan_interceptors.cc
@@ -12,11 +12,11 @@
//
//===----------------------------------------------------------------------===//
+#include "interception/interception.h"
#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_interception.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_linux.h"
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
diff --git a/compiler-rt/lib/msan/msan.cc b/compiler-rt/lib/msan/msan.cc
index b2328341eba..09622c46241 100644
--- a/compiler-rt/lib/msan/msan.cc
+++ b/compiler-rt/lib/msan/msan.cc
@@ -34,8 +34,6 @@ using namespace __sanitizer;
static THREADLOCAL int msan_expect_umr = 0;
static THREADLOCAL int msan_expected_umr_found = 0;
-static bool msan_running_under_dr;
-
// Function argument shadow. Each argument starts at the next available 8-byte
// aligned address.
SANITIZER_INTERFACE_ATTRIBUTE
@@ -63,7 +61,6 @@ SANITIZER_INTERFACE_ATTRIBUTE
THREADLOCAL u32 __msan_origin_tls;
static THREADLOCAL int is_in_symbolizer;
-static THREADLOCAL int is_in_loader;
extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins;
@@ -79,14 +76,6 @@ void EnterSymbolizer() { ++is_in_symbolizer; }
void ExitSymbolizer() { --is_in_symbolizer; }
bool IsInSymbolizer() { return is_in_symbolizer; }
-void EnterLoader() { ++is_in_loader; }
-void ExitLoader() { --is_in_loader; }
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-bool __msan_is_in_loader() { return is_in_loader; }
-}
-
static Flags msan_flags;
Flags *flags() {
@@ -394,7 +383,7 @@ void __msan_init() {
__msan_clear_on_return();
if (__msan_get_track_origins())
VPrintf(1, "msan_track_origins\n");
- if (!InitShadow(/* prot1 */ !msan_running_under_dr, /* prot2 */ true,
+ if (!InitShadow(/* prot1 */ true, /* prot2 */ true,
/* map_shadow */ true, __msan_get_track_origins())) {
Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n");
Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
@@ -498,40 +487,13 @@ int __msan_set_poison_in_malloc(int do_poison) {
return old;
}
-int __msan_has_dynamic_component() {
- return msan_running_under_dr;
-}
+int __msan_has_dynamic_component() { return false; }
NOINLINE
void __msan_clear_on_return() {
__msan_param_tls[0] = 0;
}
-static void* get_tls_base() {
- u64 p;
- asm("mov %%fs:0, %0"
- : "=r"(p) ::);
- return (void*)p;
-}
-
-int __msan_get_retval_tls_offset() {
- // volatile here is needed to avoid UB, because the compiler thinks that we
- // are doing address arithmetics on unrelated pointers, and takes some
- // shortcuts
- volatile sptr retval_tls_p = (sptr)&__msan_retval_tls;
- volatile sptr tls_base_p = (sptr)get_tls_base();
- return retval_tls_p - tls_base_p;
-}
-
-int __msan_get_param_tls_offset() {
- // volatile here is needed to avoid UB, because the compiler thinks that we
- // are doing address arithmetics on unrelated pointers, and takes some
- // shortcuts
- volatile sptr param_tls_p = (sptr)&__msan_param_tls;
- volatile sptr tls_base_p = (sptr)get_tls_base();
- return param_tls_p - tls_base_p;
-}
-
void __msan_partial_poison(const void* data, void* shadow, uptr size) {
internal_memcpy((void*)MEM_TO_SHADOW((uptr)data), shadow, size);
}
@@ -657,18 +619,6 @@ void __msan_set_death_callback(void (*callback)(void)) {
death_callback = callback;
}
-void *__msan_wrap_indirect_call(void *target) {
- return IndirectExternCall(target);
-}
-
-void __msan_dr_is_initialized() {
- msan_running_under_dr = true;
-}
-
-void __msan_set_indirect_call_wrapper(uptr wrapper) {
- SetIndirectCallWrapper(wrapper);
-}
-
#if !SANITIZER_SUPPORTS_WEAK_HOOKS
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h
index 892cf047ab5..f01940bc9b2 100644
--- a/compiler-rt/lib/msan/msan.h
+++ b/compiler-rt/lib/msan/msan.h
@@ -65,9 +65,6 @@ struct SymbolizerScope {
~SymbolizerScope() { ExitSymbolizer(); }
};
-void EnterLoader();
-void ExitLoader();
-
void MsanDie();
void PrintWarning(uptr pc, uptr bp);
void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc
index 1c7a8125a2e..aa6b1ff4bde 100644
--- a/compiler-rt/lib/msan/msan_interceptors.cc
+++ b/compiler-rt/lib/msan/msan_interceptors.cc
@@ -15,6 +15,7 @@
// sanitizer_common/sanitizer_common_interceptors.h
//===----------------------------------------------------------------------===//
+#include "interception/interception.h"
#include "msan.h"
#include "msan_chained_origin_depot.h"
#include "msan_origin.h"
@@ -25,7 +26,6 @@
#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_interception.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_linux.h"
@@ -315,11 +315,8 @@ INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
ENSURE_MSAN_INITED();
char *res = REAL(gcvt)(number, ndigit, buf);
- // DynamoRio tool will take care of unpoisoning gcvt result for us.
- if (!__msan_has_dynamic_component()) {
- SIZE_T n = REAL(strlen)(buf);
- __msan_unpoison(buf, n + 1);
- }
+ SIZE_T n = REAL(strlen)(buf);
+ __msan_unpoison(buf, n + 1);
return res;
}
@@ -349,9 +346,7 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT
#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \
ENSURE_MSAN_INITED(); \
ret_type res = REAL(func)(__VA_ARGS__); \
- if (!__msan_has_dynamic_component()) { \
- __msan_unpoison(endptr, sizeof(*endptr)); \
- } \
+ __msan_unpoison(endptr, sizeof(*endptr)); \
return res;
#define INTERCEPTOR_STRTO(ret_type, func) \
@@ -408,7 +403,7 @@ INTERCEPTOR_STRTO_BASE_LOC(unsigned long long, __strtoull_internal) // NOLINT
INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
ENSURE_MSAN_INITED();
int res = REAL(vswprintf)(str, size, format, ap);
- if (res >= 0 && !__msan_has_dynamic_component()) {
+ if (res >= 0) {
__msan_unpoison(str, 4 * (res + 1));
}
return res;
@@ -575,21 +570,16 @@ INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
ENSURE_MSAN_INITED();
char *res = REAL(fcvt)(x, a, b, c);
- if (!__msan_has_dynamic_component()) {
- __msan_unpoison(b, sizeof(*b));
- __msan_unpoison(c, sizeof(*c));
- if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
- }
+ __msan_unpoison(b, sizeof(*b));
+ __msan_unpoison(c, sizeof(*c));
+ if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
return res;
}
INTERCEPTOR(char *, getenv, char *name) {
ENSURE_MSAN_INITED();
char *res = REAL(getenv)(name);
- if (!__msan_has_dynamic_component()) {
- if (res)
- __msan_unpoison(res, REAL(strlen)(res) + 1);
- }
+ if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
return res;
}
@@ -927,17 +917,15 @@ static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
}
dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
UnpoisonParam(3);
- return IndirectExternCall(cbdata->callback)(info, size, cbdata->data);
+ return cbdata->callback(info, size, cbdata->data);
}
INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
ENSURE_MSAN_INITED();
- EnterLoader();
dl_iterate_phdr_data cbdata;
cbdata.callback = callback;
cbdata.data = data;
int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
- ExitLoader();
return res;
}
@@ -977,7 +965,7 @@ static void SignalHandler(int signo) {
typedef void (*signal_cb)(int x);
signal_cb cb =
(signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
- IndirectExternCall(cb)(signo);
+ cb(signo);
}
static void SignalAction(int signo, void *si, void *uc) {
@@ -990,7 +978,7 @@ static void SignalAction(int signo, void *si, void *uc) {
typedef void (*sigaction_cb)(int, void *, void *);
sigaction_cb cb =
(sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
- IndirectExternCall(cb)(signo, si, uc);
+ cb(signo, si, uc);
}
INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
@@ -1118,7 +1106,7 @@ struct MSanAtExitRecord {
void MSanAtExitWrapper(void *arg) {
UnpoisonParam(1);
MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
- IndirectExternCall(r->func)(r->arg);
+ r->func(r->arg);
InternalFree(r);
}
@@ -1228,12 +1216,8 @@ int OnExit() {
} while (false) // FIXME
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
-#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map) \
- if (!__msan_has_dynamic_component() && map) { \
- /* If msandr didn't clear the shadow before the initializers ran, we do */ \
- /* it ourselves afterwards. */ \
- ForEachMappedRegion((link_map *)map, __msan_unpoison); \
- }
+#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map) \
+ if (map) ForEachMappedRegion((link_map *)map, __msan_unpoison);
#include "sanitizer_common/sanitizer_common_interceptors.inc"
diff --git a/compiler-rt/lib/msan/msan_interface_internal.h b/compiler-rt/lib/msan/msan_interface_internal.h
index 401d6f9472f..8641f814bc5 100644
--- a/compiler-rt/lib/msan/msan_interface_internal.h
+++ b/compiler-rt/lib/msan/msan_interface_internal.h
@@ -122,16 +122,6 @@ void __msan_dump_shadow(const void *x, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE
int __msan_has_dynamic_component();
-// Returns x such that %fs:x is the first byte of __msan_retval_tls.
-SANITIZER_INTERFACE_ATTRIBUTE
-int __msan_get_retval_tls_offset();
-SANITIZER_INTERFACE_ATTRIBUTE
-int __msan_get_param_tls_offset();
-
-// For intercepting mmap from ld.so in msandr.
-SANITIZER_INTERFACE_ATTRIBUTE
-bool __msan_is_in_loader();
-
// For testing.
SANITIZER_INTERFACE_ATTRIBUTE
u32 __msan_get_umr_origin();
@@ -162,15 +152,6 @@ SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_unaligned_store64(uu64 *p, u64 x);
SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_dr_is_initialized();
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void *__msan_wrap_indirect_call(void *target);
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_set_indirect_call_wrapper(uptr wrapper);
-
-SANITIZER_INTERFACE_ATTRIBUTE
void __msan_set_death_callback(void (*callback)(void));
} // extern "C"
diff --git a/compiler-rt/lib/msan/msan_new_delete.cc b/compiler-rt/lib/msan/msan_new_delete.cc
index 3bae49c0cc9..9a8e56e4a28 100644
--- a/compiler-rt/lib/msan/msan_new_delete.cc
+++ b/compiler-rt/lib/msan/msan_new_delete.cc
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "msan.h"
-#include "sanitizer_common/sanitizer_interception.h"
+#include "interception/interception.h"
#if MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
diff --git a/compiler-rt/lib/msan/msan_thread.cc b/compiler-rt/lib/msan/msan_thread.cc
index 5fe99f68b79..2a1e05a4e07 100644
--- a/compiler-rt/lib/msan/msan_thread.cc
+++ b/compiler-rt/lib/msan/msan_thread.cc
@@ -73,7 +73,7 @@ thread_return_t MsanThread::ThreadStart() {
return 0;
}
- thread_return_t res = IndirectExternCall(start_routine_)(arg_);
+ thread_return_t res = start_routine_(arg_);
return res;
}
diff --git a/compiler-rt/lib/msan/tests/msan_loadable.cc b/compiler-rt/lib/msan/tests/msan_loadable.cc
index db3bf489853..06e880f90de 100644
--- a/compiler-rt/lib/msan/tests/msan_loadable.cc
+++ b/compiler-rt/lib/msan/tests/msan_loadable.cc
@@ -20,24 +20,6 @@ static void *dso_global;
// No name mangling.
extern "C" {
-__attribute__((constructor))
-void loadable_module_init(void) {
- if (!__msan_has_dynamic_component())
- return;
- // The real test is that this compare should not make an uninit.
- if (dso_global == NULL)
- dso_global = malloc(4);
-}
-
-__attribute__((destructor))
-void loadable_module_fini(void) {
- if (!__msan_has_dynamic_component())
- return;
- free(dso_global);
- // *Don't* overwrite it with NULL! That would unpoison it, but our test
- // relies on reloading at the same address and keeping the poison.
-}
-
void **get_dso_global() {
return &dso_global;
}
diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc
index c91fb0d4bb6..12012a05a9f 100644
--- a/compiler-rt/lib/msan/tests/msan_test.cc
+++ b/compiler-rt/lib/msan/tests/msan_test.cc
@@ -251,7 +251,6 @@ TEST(MemorySanitizer, ArgTest) {
TEST(MemorySanitizer, CallAndRet) {
- if (!__msan_has_dynamic_component()) return;
ReturnPoisoned<S1>();
ReturnPoisoned<S2>();
ReturnPoisoned<S4>();
@@ -494,14 +493,12 @@ TEST(MemorySanitizer, DynMem) {
static char *DynRetTestStr;
TEST(MemorySanitizer, DynRet) {
- if (!__msan_has_dynamic_component()) return;
ReturnPoisoned<S8>();
EXPECT_NOT_POISONED(clearenv());
}
TEST(MemorySanitizer, DynRet1) {
- if (!__msan_has_dynamic_component()) return;
ReturnPoisoned<S8>();
}
@@ -1452,13 +1449,8 @@ void TestOverlapMemmove() {
x[2] = 0;
memmove(x, x + 1, (size - 1) * sizeof(T));
EXPECT_NOT_POISONED(x[1]);
- if (!__msan_has_dynamic_component()) {
- // FIXME: under DR we will lose this information
- // because accesses in memmove will unpoisin the shadow.
- // We need to use our own memove implementation instead of libc's.
- EXPECT_POISONED(x[0]);
- EXPECT_POISONED(x[2]);
- }
+ EXPECT_POISONED(x[0]);
+ EXPECT_POISONED(x[2]);
delete [] x;
}
@@ -3732,56 +3724,6 @@ TEST(VectorMaddTest, mmx_pmadd_wd) {
}
#endif // defined(__clang__)
-TEST(MemorySanitizerDr, StoreInDSOTest) {
- if (!__msan_has_dynamic_component()) return;
- char* s = new char[10];
- dso_memfill(s, 9);
- EXPECT_NOT_POISONED(s[5]);
- EXPECT_POISONED(s[9]);
-}
-
-int return_poisoned_int() {
- return ReturnPoisoned<U8>();
-}
-
-TEST(MemorySanitizerDr, ReturnFromDSOTest) {
- if (!__msan_has_dynamic_component()) return;
- EXPECT_NOT_POISONED(dso_callfn(return_poisoned_int));
-}
-
-NOINLINE int TrashParamTLS(long long x, long long y, long long z) { //NOLINT
- EXPECT_POISONED(x);
- EXPECT_POISONED(y);
- EXPECT_POISONED(z);
- return 0;
-}
-
-static int CheckParamTLS(long long x, long long y, long long z) { //NOLINT
- EXPECT_NOT_POISONED(x);
- EXPECT_NOT_POISONED(y);
- EXPECT_NOT_POISONED(z);
- return 0;
-}
-
-TEST(MemorySanitizerDr, CallFromDSOTest) {
- if (!__msan_has_dynamic_component()) return;
- S8* x = GetPoisoned<S8>();
- S8* y = GetPoisoned<S8>();
- S8* z = GetPoisoned<S8>();
- EXPECT_NOT_POISONED(TrashParamTLS(*x, *y, *z));
- EXPECT_NOT_POISONED(dso_callfn1(CheckParamTLS));
-}
-
-static void StackStoreInDSOFn(int* x, int* y) {
- EXPECT_NOT_POISONED(*x);
- EXPECT_NOT_POISONED(*y);
-}
-
-TEST(MemorySanitizerDr, StackStoreInDSOTest) {
- if (!__msan_has_dynamic_component()) return;
- dso_stack_store(StackStoreInDSOFn, 1);
-}
-
TEST(MemorySanitizerOrigins, SetGet) {
EXPECT_EQ(TrackingOrigins(), __msan_get_track_origins());
if (!TrackingOrigins()) return;
diff --git a/compiler-rt/lib/msandr/CMakeLists.txt b/compiler-rt/lib/msandr/CMakeLists.txt
deleted file mode 100644
index 5a96a9dcc9e..00000000000
--- a/compiler-rt/lib/msandr/CMakeLists.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-
-if(DynamoRIO_DIR AND DrMemoryFramework_DIR)
- set(CMAKE_COMPILER_IS_GNUCC 1)
- find_package(DynamoRIO)
- find_package(DrMemoryFramework)
-
- set(arch "x86_64")
- add_library(clang_rt.msandr-${arch} SHARED msandr.cc)
- configure_DynamoRIO_client(clang_rt.msandr-${arch})
-
- function(append_target_cflags tgt cflags)
- get_property(old_cflags TARGET clang_rt.msandr-${arch} PROPERTY COMPILE_FLAGS)
- set_property(TARGET clang_rt.msandr-${arch} PROPERTY COMPILE_FLAGS "${old_cflags} ${cflags}")
- endfunction(append_target_cflags)
-
- append_target_cflags(clang_rt.msandr-${arch} "-Wno-c++11-extensions")
-
- use_DynamoRIO_extension(clang_rt.msandr-${arch} drutil)
- use_DynamoRIO_extension(clang_rt.msandr-${arch} drmgr)
- use_DynamoRIO_extension(clang_rt.msandr-${arch} drsyscall)
-
- set_target_properties(clang_rt.msandr-${arch} PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
- install(TARGETS clang_rt.msandr-${arch}
- LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})
-endif()
diff --git a/compiler-rt/lib/msandr/README.txt b/compiler-rt/lib/msandr/README.txt
deleted file mode 100644
index 81a87c69408..00000000000
--- a/compiler-rt/lib/msandr/README.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-Experimental DynamoRIO-MSAN plugin (codename "MSanDR").
-Supports Linux/x86_64 only.
-
-Building:
- 1. First, download and build DynamoRIO:
- (svn co https://dynamorio.googlecode.com/svn/trunk dr && \
- cd dr && mkdir build && cd build && \
- cmake -DDR_EXT_DRMGR_STATIC=ON -DDR_EXT_DRSYMS_STATIC=ON \
- -DDR_EXT_DRUTIL_STATIC=ON -DDR_EXT_DRWRAP_STATIC=ON \
- -DDR_EXT_DRX_STATIC=ON .. && \
- make -j10 && make install)
-
- 2. Download and build DrMemory (for DrSyscall extension)
- (svn co http://drmemory.googlecode.com/svn/trunk/ drmemory && \
- cd drmemory && mkdir build && cd build && \
- cmake -DDynamoRIO_DIR=`pwd`/../../dr/exports/cmake .. && \
- make -j10 && make install)
-
- NOTE: The line above will build a shared DrSyscall library in a non-standard
- location. This will require the use of LD_LIBRARY_PATH when running MSanDR.
- To build a static DrSyscall library (and link it into MSanDR), add
- -DDR_EXT_DRSYSCALL_STATIC=ON to the CMake invocation above, but
- beware: DrSyscall is LGPL.
-
- 3. Now, build LLVM with two extra CMake flags:
- -DDynamoRIO_DIR=<path_to_dynamorio>/exports/cmake
- -DDrMemoryFramework_DIR=<path_to_drmemory>/exports64/drmf
-
- This will build a lib/clang/$VERSION/lib/linux/libclang_rt.msandr-x86_64.so
-
-Running:
- <path_to_dynamorio>/exports/bin64/drrun -c lib/clang/$VERSION/lib/linux/libclang_rt.msandr-x86_64.so -- test_binary
-
-MSan unit tests contain several tests for MSanDR (use MemorySanitizerDr.* gtest filter).
-
-Debugging:
- Add -DCMAKE_BUILD_TYPE=Debug to the first and/or second cmake invocation(s).
- Add -debug -v to drrun invocation line (right before -c).
- Add -checklevel 1 to drrun (as the first argument) to make debug DR faster.
-
diff --git a/compiler-rt/lib/msandr/msandr.cc b/compiler-rt/lib/msandr/msandr.cc
deleted file mode 100644
index 5159ddbddce..00000000000
--- a/compiler-rt/lib/msandr/msandr.cc
+++ /dev/null
@@ -1,900 +0,0 @@
-//===-- msandr.cc ---------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of MemorySanitizer.
-//
-// DynamoRio client for MemorySanitizer.
-//
-// MemorySanitizer requires that all program code is instrumented. Any memory
-// store that can turn an uninitialized value into an initialized value must be
-// observed by the tool, otherwise we risk reporting a false UMR.
-//
-// This also includes any libraries that the program depends on.
-//
-// In the case when rebuilding all program dependencies with MemorySanitizer is
-// problematic, an experimental MSanDR tool (the code you are currently looking
-// at) can be used. It is a DynamoRio-based tool that uses dynamic
-// instrumentation to
-// * Unpoison all memory stores.
-// * Unpoison TLS slots used by MemorySanitizer to pass function arguments and
-// return value shadow on anything that looks like a function call or a return
-// from a function.
-//
-// This tool does not detect the use of uninitialized values in uninstrumented
-// libraries. It merely gets rid of false positives by marking all data that
-// passes through uninstrumented code as fully initialized.
-//===----------------------------------------------------------------------===//
-
-#include <dr_api.h>
-#include <drutil.h>
-#include <drmgr.h>
-#include <drsyscall.h>
-
-#include <sys/mman.h>
-#include <sys/syscall.h> /* for SYS_mmap */
-
-#include <string.h>
-
-// XXX: it seems setting macro in CMakeLists.txt does not work,
-// so manually set it here now.
-
-// Building msandr client for running in DynamoRIO hybrid mode,
-// which allows some module running natively.
-// TODO: turn it on by default when hybrid is stable enough
-// #define MSANDR_NATIVE_EXEC
-
-#ifndef MSANDR_NATIVE_EXEC
-#include <algorithm>
-#include <set>
-#include <string>
-#include <vector>
-#endif
-
-#define TESTALL(mask, var) (((mask) & (var)) == (mask))
-#define TESTANY(mask, var) (((mask) & (var)) != 0)
-
-#define CHECK_IMPL(condition, file, line) \
- do { \
- if (!(condition)) { \
- dr_printf("Check failed: `%s`\nat %s:%d\n", #condition, file, line); \
- dr_abort(); \
- } \
- } while (0) // TODO: stacktrace
-
-#define CHECK(condition) CHECK_IMPL(condition, __FILE__, __LINE__)
-
-#define VERBOSITY 0
-
-// Building msandr client for standalone test that does not need to
-// run with msan build executables. Disable by default.
-// #define MSANDR_STANDALONE_TEST
-
-#define NUM_TLS_RETVAL 1
-#define NUM_TLS_PARAM 6
-
-#ifdef MSANDR_STANDALONE_TEST
-// For testing purpose, we map app to shadow memory at [0x100000, 0x20000).
-// Normally, the app starts at 0x400000:
-// 00400000-004e0000 r-xp 00000000 fc:00 524343 /bin/bash
-// so there should be no problem.
-# define SHADOW_MEMORY_BASE ((void *)0x100000)
-# define SHADOW_MEMORY_SIZE (0x100000)
-# define SHADOW_MEMORY_MASK (SHADOW_MEMORY_SIZE - 4 /* to avoid overflow */)
-#else
-// shadow memory range [0x200000000000, 0x400000000000)
-// assuming no app memory below 0x200000000000
-# define SHADOW_MEMORY_MASK 0x3fffffffffffULL
-#endif /* MSANDR_STANDALONE_TEST */
-
-typedef void *(*WrapperFn)(void *);
-extern "C" void __msan_set_indirect_call_wrapper(WrapperFn wrapper);
-extern "C" void __msan_dr_is_initialized();
-
-namespace {
-
-int msan_retval_tls_offset;
-int msan_param_tls_offset;
-
-#ifndef MSANDR_NATIVE_EXEC
-class ModuleData {
-public:
- ModuleData();
- ModuleData(const module_data_t *info);
- // Yes, we want default copy, assign, and dtor semantics.
-
-public:
- app_pc start_;
- app_pc end_;
- // Full path to the module.
- std::string path_;
- module_handle_t handle_;
- bool should_instrument_;
- bool executed_;
-};
-
-// A vector of loaded modules sorted by module bounds. We lookup the current PC
-// in here from the bb event. This is better than an rb tree because the lookup
-// is faster and the bb event occurs far more than the module load event.
-std::vector<ModuleData> g_module_list;
-
-ModuleData::ModuleData()
- : start_(NULL), end_(NULL), path_(""), handle_(NULL),
- should_instrument_(false), executed_(false) {
-}
-
-ModuleData::ModuleData(const module_data_t *info)
- : start_(info->start), end_(info->end), path_(info->full_path),
- handle_(info->handle),
- // We'll check the black/white lists later and adjust this.
- should_instrument_(true), executed_(false) {
-}
-#endif /* !MSANDR_NATIVE_EXEC */
-
-int(*__msan_get_retval_tls_offset)();
-int(*__msan_get_param_tls_offset)();
-void (*__msan_unpoison)(void *base, size_t size);
-bool (*__msan_is_in_loader)();
-
-#ifdef MSANDR_STANDALONE_TEST
-uint mock_msan_retval_tls_offset;
-uint mock_msan_param_tls_offset;
-static int mock_msan_get_retval_tls_offset() {
- return (int)mock_msan_retval_tls_offset;
-}
-
-static int mock_msan_get_param_tls_offset() {
- return (int)mock_msan_param_tls_offset;
-}
-
-static void mock_msan_unpoison(void *base, size_t size) {
- /* do nothing */
-}
-
-static bool mock_msan_is_in_loader() {
- return false;
-}
-#endif /* MSANDR_STANDALONE_TEST */
-
-static generic_func_t LookupCallback(module_data_t *app, const char *name) {
-#ifdef MSANDR_STANDALONE_TEST
- if (strcmp("__msan_get_retval_tls_offset", name) == 0) {
- return (generic_func_t)mock_msan_get_retval_tls_offset;
- } else if (strcmp("__msan_get_param_tls_offset", name) == 0) {
- return (generic_func_t)mock_msan_get_param_tls_offset;
- } else if (strcmp("__msan_unpoison", name) == 0) {
- return (generic_func_t)mock_msan_unpoison;
- } else if (strcmp("__msan_is_in_loader", name) == 0) {
- return (generic_func_t)mock_msan_is_in_loader;
- }
- CHECK(false);
- return NULL;
-#else /* !MSANDR_STANDALONE_TEST */
- generic_func_t callback = dr_get_proc_address(app->handle, name);
- if (callback == NULL) {
- dr_printf("Couldn't find `%s` in %s\n", name, app->full_path);
- CHECK(callback);
- }
- return callback;
-#endif /* !MSANDR_STANDALONE_TEST */
-}
-
-void InitializeMSanCallbacks() {
- module_data_t *app = dr_lookup_module_by_name(dr_get_application_name());
- if (!app) {
- dr_printf("%s - oops, dr_lookup_module_by_name failed!\n",
- dr_get_application_name());
- CHECK(app);
- }
-
- __msan_get_retval_tls_offset = (int (*)())
- LookupCallback(app, "__msan_get_retval_tls_offset");
- __msan_get_param_tls_offset = (int (*)())
- LookupCallback(app, "__msan_get_param_tls_offset");
- __msan_unpoison = (void(*)(void *, size_t))
- LookupCallback(app, "__msan_unpoison");
- __msan_is_in_loader = (bool (*)())
- LookupCallback(app, "__msan_is_in_loader");
-
- dr_free_module_data(app);
-}
-
-// FIXME: Handle absolute addresses and PC-relative addresses.
-// FIXME: Handle TLS accesses via FS or GS. DR assumes all other segments have
-// a zero base anyway.
-bool OperandIsInteresting(opnd_t opnd) {
- return (opnd_is_base_disp(opnd) && opnd_get_segment(opnd) != DR_SEG_FS &&
- opnd_get_segment(opnd) != DR_SEG_GS);
-}
-
-bool WantToInstrument(instr_t *instr) {
- // TODO: skip push instructions?
- switch (instr_get_opcode(instr)) {
- // FIXME: support the instructions excluded below:
- case OP_rep_cmps:
- // f3 a6 rep cmps %ds:(%rsi) %es:(%rdi) %rsi %rdi %rcx -> %rsi %rdi %rcx
- return false;
- }
-
- // Labels appear due to drutil_expand_rep_string()
- if (instr_is_label(instr))
- return false;
-
- CHECK(instr_ok_to_mangle(instr) == true);
-
- if (instr_writes_memory(instr)) {
- for (int d = 0; d < instr_num_dsts(instr); d++) {
- opnd_t op = instr_get_dst(instr, d);
- if (OperandIsInteresting(op))
- return true;
- }
- }
-
- return false;
-}
-
-#define PRE(at, what) instrlist_meta_preinsert(bb, at, INSTR_CREATE_##what);
-#define PREF(at, what) instrlist_meta_preinsert(bb, at, what);
-
-void InstrumentMops(void *drcontext, instrlist_t *bb, instr_t *instr, opnd_t op,
- bool is_write) {
- bool need_to_restore_eflags = false;
- uint flags = instr_get_arith_flags(instr);
- // TODO: do something smarter with flags and spills in general?
- // For example, spill them only once for a sequence of instrumented
- // instructions that don't change/read flags.
-
- if (!TESTALL(EFLAGS_WRITE_6, flags) || TESTANY(EFLAGS_READ_6, flags)) {
- if (VERBOSITY > 1)
- dr_printf("Spilling eflags...\n");
- need_to_restore_eflags = true;
- // TODO: Maybe sometimes don't need to 'seto'.
- // TODO: Maybe sometimes don't want to spill XAX here?
- // TODO: No need to spill XAX here if XAX is not used in the BB.
- dr_save_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_1);
- dr_save_arith_flags_to_xax(drcontext, bb, instr);
- dr_save_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_3);
- dr_restore_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_1);
- }
-
-#if 0
- dr_printf("==DRMSAN== DEBUG: %d %d %d %d %d %d\n",
- opnd_is_memory_reference(op), opnd_is_base_disp(op),
- opnd_is_base_disp(op) ? opnd_get_index(op) : -1,
- opnd_is_far_memory_reference(op), opnd_is_reg_pointer_sized(op),
- opnd_is_base_disp(op) ? opnd_get_disp(op) : -1);
-#endif
-
- reg_id_t R1;
- bool address_in_R1 = false;
- if (opnd_is_base_disp(op) && opnd_get_index(op) == DR_REG_NULL &&
- opnd_get_disp(op) == 0) {
- // If this is a simple access with no offset or index, we can just use the
- // base for R1.
- address_in_R1 = true;
- R1 = opnd_get_base(op);
- } else {
- // Otherwise, we need to compute the addr into R1.
- // TODO: reuse some spare register? e.g. r15 on x64
- // TODO: might be used as a non-mem-ref register?
- R1 = DR_REG_XAX;
- }
- CHECK(reg_is_pointer_sized(R1)); // otherwise R2 may be wrong.
-
- // Pick R2 from R8 to R15.
- // It's OK if the instr uses R2 elsewhere, since we'll restore it before instr.
- reg_id_t R2;
- for (R2 = DR_REG_R8; R2 <= DR_REG_R15; R2++) {
- if (!opnd_uses_reg(op, R2))
- break;
- }
- CHECK((R2 <= DR_REG_R15) && R1 != R2);
-
- // Save the current values of R1 and R2.
- dr_save_reg(drcontext, bb, instr, R1, SPILL_SLOT_1);
- // TODO: Something smarter than spilling a "fixed" register R2?
- dr_save_reg(drcontext, bb, instr, R2, SPILL_SLOT_2);
-
- if (!address_in_R1)
- CHECK(drutil_insert_get_mem_addr(drcontext, bb, instr, op, R1, R2));
- PRE(instr, mov_imm(drcontext, opnd_create_reg(R2),
- OPND_CREATE_INT64(SHADOW_MEMORY_MASK)));
- PRE(instr, and(drcontext, opnd_create_reg(R1), opnd_create_reg(R2)));
-#ifdef MSANDR_STANDALONE_TEST
- PRE(instr, add(drcontext, opnd_create_reg(R1),
- OPND_CREATE_INT32(SHADOW_MEMORY_BASE)));
-#endif
- // There is no mov_st of a 64-bit immediate, so...
- opnd_size_t op_size = opnd_get_size(op);
- CHECK(op_size != OPSZ_NA);
- uint access_size = opnd_size_in_bytes(op_size);
- if (access_size <= 4 || op_size == OPSZ_PTR /* x64 support sign extension */) {
- instr_t *label = INSTR_CREATE_label(drcontext);
- opnd_t immed;
- if (op_size == OPSZ_PTR || op_size == OPSZ_4)
- immed = OPND_CREATE_INT32(0);
- else
- immed = opnd_create_immed_int((ptr_int_t) 0, op_size);
- // we check if target is 0 before write to reduce unnecessary memory stores.
- PRE(instr, cmp(drcontext,
- opnd_create_base_disp(R1, DR_REG_NULL, 0, 0, op_size),
- immed));
- PRE(instr, jcc(drcontext, OP_je, opnd_create_instr(label)));
- PRE(instr, mov_st(drcontext,
- opnd_create_base_disp(R1, DR_REG_NULL, 0, 0, op_size),
- immed));
- PREF(instr, label);
- } else {
- // FIXME: tail?
- for (uint ofs = 0; ofs < access_size; ofs += 4) {
- instr_t *label = INSTR_CREATE_label(drcontext);
- opnd_t immed = OPND_CREATE_INT32(0);
- PRE(instr, cmp(drcontext, OPND_CREATE_MEM32(R1, ofs), immed));
- PRE(instr, jcc(drcontext, OP_je, opnd_create_instr(label)));
- PRE(instr, mov_st(drcontext, OPND_CREATE_MEM32(R1, ofs), immed));
- PREF(instr, label)
- }
- }
-
- // Restore the registers and flags.
- dr_restore_reg(drcontext, bb, instr, R1, SPILL_SLOT_1);
- dr_restore_reg(drcontext, bb, instr, R2, SPILL_SLOT_2);
-
- // TODO: move aflags save/restore to per instr instead of per opnd
- if (need_to_restore_eflags) {
- if (VERBOSITY > 1)
- dr_printf("Restoring eflags\n");
- // TODO: Check if it's reverse to the dr_restore_reg above and optimize.
- dr_save_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_1);
- dr_restore_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_3);
- dr_restore_arith_flags_from_xax(drcontext, bb, instr);
- dr_restore_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_1);
- }
-
- // The original instruction is left untouched. The above instrumentation is just
- // a prefix.
-}
-
-void InstrumentReturn(void *drcontext, instrlist_t *bb, instr_t *instr) {
-#ifdef MSANDR_STANDALONE_TEST
- PRE(instr,
- mov_st(drcontext,
- opnd_create_far_base_disp(DR_SEG_GS /* DR's TLS */,
- DR_REG_NULL, DR_REG_NULL,
- 0, msan_retval_tls_offset,
- OPSZ_PTR),
- OPND_CREATE_INT32(0)));
-#else /* !MSANDR_STANDALONE_TEST */
-# ifdef MSANDR_NATIVE_EXEC
- /* For optimized native exec, -mangle_app_seg and -private_loader are turned off,
- * so we can reference msan_retval_tls_offset directly.
- */
- PRE(instr,
- mov_st(drcontext,
- opnd_create_far_base_disp(DR_SEG_FS, DR_REG_NULL, DR_REG_NULL, 0,
- msan_retval_tls_offset, OPSZ_PTR),
- OPND_CREATE_INT32(0)));
-# else /* !MSANDR_NATIVE_EXEC */
- /* XXX: the code below only works if -mangle_app_seg and -private_loader,
- * which is turned off for optimized native exec
- */
- dr_save_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_1);
-
- // Clobbers nothing except xax.
- bool res =
- dr_insert_get_seg_base(drcontext, bb, instr, DR_SEG_FS, DR_REG_XAX);
- CHECK(res);
-
- // TODO: unpoison more bytes?
- PRE(instr,
- mov_st(drcontext, OPND_CREATE_MEM64(DR_REG_XAX, msan_retval_tls_offset),
- OPND_CREATE_INT32(0)));
-
- dr_restore_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_1);
-# endif /* !MSANDR_NATIVE_EXEC */
- // The original instruction is left untouched. The above instrumentation is just
- // a prefix.
-#endif /* !MSANDR_STANDALONE_TEST */
-}
-
-void InstrumentIndirectBranch(void *drcontext, instrlist_t *bb,
- instr_t *instr) {
-#ifdef MSANDR_STANDALONE_TEST
- for (int i = 0; i < NUM_TLS_PARAM; ++i) {
- PRE(instr,
- mov_st(drcontext,
- opnd_create_far_base_disp(DR_SEG_GS /* DR's TLS */,
- DR_REG_NULL, DR_REG_NULL,
- 0,
- msan_param_tls_offset +
- i * sizeof(void *),
- OPSZ_PTR),
- OPND_CREATE_INT32(0)));
- }
-#else /* !MSANDR_STANDALONE_TEST */
-# ifdef MSANDR_NATIVE_EXEC
- for (int i = 0; i < NUM_TLS_PARAM; ++i) {
- PRE(instr,
- mov_st(drcontext,
- opnd_create_far_base_disp(DR_SEG_FS, DR_REG_NULL, DR_REG_NULL, 0,
- msan_param_tls_offset + i*sizeof(void*),
- OPSZ_PTR),
- OPND_CREATE_INT32(0)));
- }
-# else /* !MSANDR_NATIVE_EXEC */
- /* XXX: the code below only works if -mangle_app_seg and -private_loader,
- * which is turned off for optimized native exec
- */
- dr_save_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_1);
-
- // Clobbers nothing except xax.
- bool res =
- dr_insert_get_seg_base(drcontext, bb, instr, DR_SEG_FS, DR_REG_XAX);
- CHECK(res);
-
- // TODO: unpoison more bytes?
- for (int i = 0; i < NUM_TLS_PARAM; ++i) {
- PRE(instr,
- mov_st(drcontext, OPND_CREATE_MEMPTR(DR_REG_XAX, msan_param_tls_offset +
- i * sizeof(void *)),
- OPND_CREATE_INT32(0)));
- }
-
- dr_restore_reg(drcontext, bb, instr, DR_REG_XAX, SPILL_SLOT_1);
-# endif /* !MSANDR_NATIVE_EXEC */
- // The original instruction is left untouched. The above instrumentation is just
- // a prefix.
-#endif /* !MSANDR_STANDALONE_TEST */
-}
-
-#ifndef MSANDR_NATIVE_EXEC
-// For use with binary search. Modules shouldn't overlap, so we shouldn't have
-// to look at end_. If that can happen, we won't support such an application.
-bool ModuleDataCompareStart(const ModuleData &left, const ModuleData &right) {
- return left.start_ < right.start_;
-}
-
-// Look up the module containing PC. Should be relatively fast, as its called
-// for each bb instrumentation.
-ModuleData *LookupModuleByPC(app_pc pc) {
- ModuleData fake_mod_data;
- fake_mod_data.start_ = pc;
- std::vector<ModuleData>::iterator it =
- lower_bound(g_module_list.begin(), g_module_list.end(), fake_mod_data,
- ModuleDataCompareStart);
- // if (it == g_module_list.end())
- // return NULL;
- if (it == g_module_list.end() || pc < it->start_)
- --it;
- CHECK(it->start_ <= pc);
- if (pc >= it->end_) {
- // We're past the end of this module. We shouldn't be in the next module,
- // or lower_bound lied to us.
- ++it;
- CHECK(it == g_module_list.end() || pc < it->start_);
- return NULL;
- }
-
- // OK, we found the module.
- return &*it;
-}
-
-bool ShouldInstrumentNonModuleCode() { return true; }
-
-bool ShouldInstrumentModule(ModuleData *mod_data) {
- // TODO(rnk): Flags for blacklist would get wired in here.
- generic_func_t p =
- dr_get_proc_address(mod_data->handle_, "__msan_track_origins");
- return !p;
-}
-
-bool ShouldInstrumentPc(app_pc pc, ModuleData **pmod_data) {
- ModuleData *mod_data = LookupModuleByPC(pc);
- if (pmod_data)
- *pmod_data = mod_data;
- if (mod_data != NULL) {
- // This module is on a blacklist.
- if (!mod_data->should_instrument_) {
- return false;
- }
- } else if (!ShouldInstrumentNonModuleCode()) {
- return false;
- }
- return true;
-}
-#endif /* !MSANDR_NATIVE_CLIENT */
-
-// TODO(rnk): Make sure we instrument after __msan_init.
-dr_emit_flags_t
-event_basic_block_app2app(void *drcontext, void *tag, instrlist_t *bb,
- bool for_trace, bool translating) {
-#ifndef MSANDR_NATIVE_EXEC
- app_pc pc = dr_fragment_app_pc(tag);
- if (ShouldInstrumentPc(pc, NULL))
- CHECK(drutil_expand_rep_string(drcontext, bb));
-#else /* MSANDR_NATIVE_EXEC */
- CHECK(drutil_expand_rep_string(drcontext, bb));
-#endif /* MSANDR_NATIVE_EXEC */
- return DR_EMIT_PERSISTABLE;
-}
-
-dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
- bool for_trace, bool translating) {
- app_pc pc = dr_fragment_app_pc(tag);
-#ifndef MSANDR_NATIVE_EXEC
- ModuleData *mod_data;
-
- if (!ShouldInstrumentPc(pc, &mod_data))
- return DR_EMIT_PERSISTABLE;
-
- if (VERBOSITY > 1)
- dr_printf("============================================================\n");
- if (VERBOSITY > 0) {
- std::string mod_path = (mod_data ? mod_data->path_ : "<no module, JITed?>");
- if (mod_data && !mod_data->executed_) {
- mod_data->executed_ = true; // Nevermind this race.
- dr_printf("Executing from new module: %s\n", mod_path.c_str());
- }
- dr_printf("BB to be instrumented: %p [from %s]; translating = %s\n", pc,
- mod_path.c_str(), translating ? "true" : "false");
- if (mod_data) {
- // Match standard sanitizer trace format for free symbols.
- // #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45)
- dr_printf(" #0 %p (%s+%p)\n", pc, mod_data->path_.c_str(),
- pc - mod_data->start_);
- }
- }
-#endif /* !MSANDR_NATIVE_EXEC */
-
- if (VERBOSITY > 1) {
- instrlist_disassemble(drcontext, pc, bb, STDOUT);
- instr_t *instr;
- for (instr = instrlist_first(bb); instr; instr = instr_get_next(instr)) {
- dr_printf("opcode: %d\n", instr_get_opcode(instr));
- }
- }
-
- for (instr_t *i = instrlist_first(bb); i != NULL; i = instr_get_next(i)) {
- int opcode = instr_get_opcode(i);
- if (opcode == OP_ret || opcode == OP_ret_far) {
- InstrumentReturn(drcontext, bb, i);
- continue;
- }
-
- // These instructions hopefully cover all cases where control is transferred
- // to a function in a different module (we only care about calls into
- // compiler-instrumented modules).
- // * call_ind is used for normal indirect calls.
- // * jmp_ind is used for indirect tail calls, and calls through PLT (PLT
- // stub includes a jump to an address from GOT).
- if (opcode == OP_call_ind || opcode == OP_call_far_ind ||
- opcode == OP_jmp_ind || opcode == OP_jmp_far_ind) {
- InstrumentIndirectBranch(drcontext, bb, i);
- continue;
- }
-
- if (!WantToInstrument(i))
- continue;
-
- if (VERBOSITY > 1) {
- app_pc orig_pc = dr_fragment_app_pc(tag);
- uint flags = instr_get_arith_flags(i);
- dr_printf("+%d -> to be instrumented! [opcode=%d, flags = 0x%08X]\n",
- instr_get_app_pc(i) - orig_pc, instr_get_opcode(i), flags);
- }
-
- if (instr_writes_memory(i)) {
- // Instrument memory writes
- // bool instrumented_anything = false;
- for (int d = 0; d < instr_num_dsts(i); d++) {
- opnd_t op = instr_get_dst(i, d);
- if (!OperandIsInteresting(op))
- continue;
-
- // CHECK(!instrumented_anything);
- // instrumented_anything = true;
- InstrumentMops(drcontext, bb, i, op, true);
- break; // only instrumenting the first dst
- }
- }
- }
-
-// TODO: optimize away redundant restore-spill pairs?
-
- if (VERBOSITY > 1) {
- pc = dr_fragment_app_pc(tag);
- dr_printf("\nFinished instrumenting dynamorio_basic_block(PC=" PFX ")\n", pc);
- instrlist_disassemble(drcontext, pc, bb, STDOUT);
- }
- return DR_EMIT_PERSISTABLE;
-}
-
-#ifndef MSANDR_NATIVE_EXEC
-void event_module_load(void *drcontext, const module_data_t *info,
- bool loaded) {
- // Insert the module into the list while maintaining the ordering.
- ModuleData mod_data(info);
- std::vector<ModuleData>::iterator it =
- upper_bound(g_module_list.begin(), g_module_list.end(), mod_data,
- ModuleDataCompareStart);
- it = g_module_list.insert(it, mod_data);
- // Check if we should instrument this module.
- it->should_instrument_ = ShouldInstrumentModule(&*it);
- dr_module_set_should_instrument(info->handle, it->should_instrument_);
-
- if (VERBOSITY > 0)
- dr_printf("==DRMSAN== Loaded module: %s [%p...%p], instrumentation is %s\n",
- info->full_path, info->start, info->end,
- it->should_instrument_ ? "on" : "off");
-}
-
-void event_module_unload(void *drcontext, const module_data_t *info) {
- if (VERBOSITY > 0)
- dr_printf("==DRMSAN== Unloaded module: %s [%p...%p]\n", info->full_path,
- info->start, info->end);
-
- // Remove the module from the list.
- ModuleData mod_data(info);
- std::vector<ModuleData>::iterator it =
- lower_bound(g_module_list.begin(), g_module_list.end(), mod_data,
- ModuleDataCompareStart);
- // It's a bug if we didn't actually find the module.
- CHECK(it != g_module_list.end() && it->start_ == mod_data.start_ &&
- it->end_ == mod_data.end_ && it->path_ == mod_data.path_);
- g_module_list.erase(it);
-}
-#endif /* !MSANDR_NATIVE_EXEC */
-
-void event_exit() {
- // Clean up so DR doesn't tell us we're leaking memory.
- drsys_exit();
- drutil_exit();
- drmgr_exit();
-
-#ifdef MSANDR_STANDALONE_TEST
- /* free tls */
- bool res;
- res = dr_raw_tls_cfree(msan_retval_tls_offset, NUM_TLS_RETVAL);
- CHECK(res);
- res = dr_raw_tls_cfree(msan_param_tls_offset, NUM_TLS_PARAM);
- CHECK(res);
- /* we do not bother to free the shadow memory */
-#endif /* !MSANDR_STANDALONE_TEST */
- if (VERBOSITY > 0)
- dr_printf("==DRMSAN== DONE\n");
-}
-
-bool event_filter_syscall(void *drcontext, int sysnum) {
- // FIXME: only intercept syscalls with memory effects.
- return true; /* intercept everything */
-}
-
-bool drsys_iter_memarg_cb(drsys_arg_t *arg, void *user_data) {
- CHECK(arg->valid);
-
- if (arg->pre)
- return true;
- if (!TESTANY(DRSYS_PARAM_OUT, arg->mode))
- return true;
-
- size_t sz = arg->size;
-
- if (sz > 0xFFFFFFFF) {
- drmf_status_t res;
- drsys_syscall_t *syscall = (drsys_syscall_t *)user_data;
- const char *name;
- res = drsys_syscall_name(syscall, &name);
- CHECK(res == DRMF_SUCCESS);
-
- dr_printf("SANITY: syscall '%s' arg %d writes %llu bytes memory?!"
- " Clipping to %llu.\n",
- name, arg->ordinal, (unsigned long long) sz,
- (unsigned long long)(sz & 0xFFFFFFFF));
- }
-
- if (VERBOSITY > 0) {
- drmf_status_t res;
- drsys_syscall_t *syscall = (drsys_syscall_t *)user_data;
- const char *name;
- res = drsys_syscall_name(syscall, &name);
- CHECK(res == DRMF_SUCCESS);
- dr_printf("drsyscall: syscall '%s' arg %d wrote range [%p, %p)\n",
- name, arg->ordinal, arg->start_addr,
- (char *)arg->start_addr + sz);
- }
-
- // We don't switch to the app context because __msan_unpoison() doesn't need
- // TLS segments.
- __msan_unpoison(arg->start_addr, sz);
-
- return true; /* keep going */
-}
-
-bool event_pre_syscall(void *drcontext, int sysnum) {
- drsys_syscall_t *syscall;
- drsys_sysnum_t sysnum_full;
- bool known;
- drsys_param_type_t ret_type;
- drmf_status_t res;
- const char *name;
-
- res = drsys_cur_syscall(drcontext, &syscall);
- CHECK(res == DRMF_SUCCESS);
-
- res = drsys_syscall_number(syscall, &sysnum_full);
- CHECK(res == DRMF_SUCCESS);
- CHECK(sysnum == sysnum_full.number);
-
- res = drsys_syscall_is_known(syscall, &known);
- CHECK(res == DRMF_SUCCESS);
-
- res = drsys_syscall_name(syscall, &name);
- CHECK(res == DRMF_SUCCESS);
-
- res = drsys_syscall_return_type(syscall, &ret_type);
- CHECK(res == DRMF_SUCCESS);
- CHECK(ret_type != DRSYS_TYPE_INVALID);
- CHECK(!known || ret_type != DRSYS_TYPE_UNKNOWN);
-
- res = drsys_iterate_memargs(drcontext, drsys_iter_memarg_cb, NULL);
- CHECK(res == DRMF_SUCCESS);
-
- return true;
-}
-
-static bool IsInLoader(void *drcontext) {
- // TODO: This segment swap is inefficient. DR should just let us query the
- // app segment base, which it has. Alternatively, if we disable
- // -mangle_app_seg, then we won't need the swap.
- bool need_swap = !dr_using_app_state(drcontext);
- if (need_swap)
- dr_switch_to_app_state(drcontext);
- bool is_in_loader = __msan_is_in_loader();
- if (need_swap)
- dr_switch_to_dr_state(drcontext);
- return is_in_loader;
-}
-
-void event_post_syscall(void *drcontext, int sysnum) {
- drsys_syscall_t *syscall;
- drsys_sysnum_t sysnum_full;
- bool success = false;
- drmf_status_t res;
-
- res = drsys_cur_syscall(drcontext, &syscall);
- CHECK(res == DRMF_SUCCESS);
-
- res = drsys_syscall_number(syscall, &sysnum_full);
- CHECK(res == DRMF_SUCCESS);
- CHECK(sysnum == sysnum_full.number);
-
- res = drsys_syscall_succeeded(syscall, dr_syscall_get_result(drcontext),
- &success);
- CHECK(res == DRMF_SUCCESS);
-
- if (success) {
- res =
- drsys_iterate_memargs(drcontext, drsys_iter_memarg_cb, (void *)syscall);
- CHECK(res == DRMF_SUCCESS);
- }
-
- // Our normal mmap interceptor can't intercept calls from the loader itself.
- // This means we don't clear the shadow for calls to dlopen. For now, we
- // solve this by intercepting mmap from ld.so here, but ideally we'd have a
- // solution that doesn't rely on msandr.
- //
- // Be careful not to intercept maps done by the msan rtl. Otherwise we end up
- // unpoisoning vast regions of memory and OOMing.
- // TODO: __msan_unpoison() could "flush" large regions of memory like tsan
- // does instead of doing a large memset. However, we need the memory to be
- // zeroed, where as tsan does not, so plain madvise is not enough.
- if (success && (sysnum == SYS_mmap IF_NOT_X64(|| sysnum == SYS_mmap2))) {
- if (IsInLoader(drcontext)) {
- app_pc base = (app_pc)dr_syscall_get_result(drcontext);
- ptr_uint_t size;
- drmf_status_t res = drsys_pre_syscall_arg(drcontext, 1, &size);
- CHECK(res == DRMF_SUCCESS);
- if (VERBOSITY > 0)
- dr_printf("unpoisoning for dlopen: [%p-%p]\n", base, base + size);
- // We don't switch to the app context because __msan_unpoison() doesn't
- // need TLS segments.
- __msan_unpoison(base, size);
- }
- }
-}
-
-} // namespace
-
-DR_EXPORT void dr_init(client_id_t id) {
- drmf_status_t res;
-
- drmgr_init();
- drutil_init();
-
-#ifndef MSANDR_NATIVE_EXEC
- // We should use drconfig to ignore these applications.
- std::string app_name = dr_get_application_name();
- // This blacklist will still run these apps through DR's code cache. On the
- // other hand, we are able to follow children of these apps.
- // FIXME: Once DR has detach, we could just detach here. Alternatively,
- // if DR had a fork or exec hook to let us decide there, that would be nice.
- // FIXME: make the blacklist cmd-adjustable.
- if (app_name == "python" || app_name == "python2.7" || app_name == "bash" ||
- app_name == "sh" || app_name == "true" || app_name == "exit" ||
- app_name == "yes" || app_name == "echo")
- return;
-#endif /* !MSANDR_NATIVE_EXEC */
-
- drsys_options_t ops;
- memset(&ops, 0, sizeof(ops));
- ops.struct_size = sizeof(ops);
- ops.analyze_unknown_syscalls = false;
-
- res = drsys_init(id, &ops);
- CHECK(res == DRMF_SUCCESS);
-
- dr_register_filter_syscall_event(event_filter_syscall);
- drmgr_register_pre_syscall_event(event_pre_syscall);
- drmgr_register_post_syscall_event(event_post_syscall);
- res = drsys_filter_all_syscalls();
- CHECK(res == DRMF_SUCCESS);
-
-#ifdef MSANDR_STANDALONE_TEST
- reg_id_t reg_seg;
- /* alloc tls */
- if (!dr_raw_tls_calloc(&reg_seg, &mock_msan_retval_tls_offset, NUM_TLS_RETVAL, 0))
- CHECK(false);
- CHECK(reg_seg == DR_SEG_GS /* x64 only! */);
- if (!dr_raw_tls_calloc(&reg_seg, &mock_msan_param_tls_offset, NUM_TLS_PARAM, 0))
- CHECK(false);
- CHECK(reg_seg == DR_SEG_GS /* x64 only! */);
- /* alloc shadow memory */
- if (mmap(SHADOW_MEMORY_BASE, SHADOW_MEMORY_SIZE, PROT_READ|PROT_WRITE,
- MAP_PRIVATE | MAP_ANON, -1, 0) != SHADOW_MEMORY_BASE) {
- CHECK(false);
- }
-#endif /* MSANDR_STANDALONE_TEST */
- InitializeMSanCallbacks();
-
- // FIXME: the shadow is initialized earlier when DR calls one of our wrapper
- // functions. This may change one day.
- // TODO: make this more robust.
-
- void *drcontext = dr_get_current_drcontext();
-
- dr_switch_to_app_state(drcontext);
- msan_retval_tls_offset = __msan_get_retval_tls_offset();
- msan_param_tls_offset = __msan_get_param_tls_offset();
- dr_switch_to_dr_state(drcontext);
- if (VERBOSITY > 0) {
- dr_printf("__msan_retval_tls offset: %d\n", msan_retval_tls_offset);
- dr_printf("__msan_param_tls offset: %d\n", msan_param_tls_offset);
- }
-
- // Standard DR events.
- dr_register_exit_event(event_exit);
-
- drmgr_priority_t priority = {
- sizeof(priority), /* size of struct */
- "msandr", /* name of our operation */
- NULL, /* optional name of operation we should precede */
- NULL, /* optional name of operation we should follow */
- 0
- }; /* numeric priority */
-
- drmgr_register_bb_app2app_event(event_basic_block_app2app, &priority);
- drmgr_register_bb_instru2instru_event(event_basic_block, &priority);
-#ifndef MSANDR_NATIVE_EXEC
- drmgr_register_module_load_event(event_module_load);
- drmgr_register_module_unload_event(event_module_unload);
-#endif /* MSANDR_NATIVE_EXEC */
- __msan_dr_is_initialized();
- __msan_set_indirect_call_wrapper(dr_app_handle_mbr_target);
- if (VERBOSITY > 0)
- dr_printf("==MSANDR== Starting!\n");
-}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index d1e9d369852..c1e2101ea83 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -523,23 +523,6 @@ const uptr kPthreadDestructorIterations = 0;
// Callback type for iterating over a set of memory ranges.
typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
-#if (SANITIZER_FREEBSD || SANITIZER_LINUX) && !defined(SANITIZER_GO)
-extern uptr indirect_call_wrapper;
-void SetIndirectCallWrapper(uptr wrapper);
-
-template <typename F>
-F IndirectExternCall(F f) {
- typedef F (*WrapF)(F);
- return indirect_call_wrapper ? ((WrapF)indirect_call_wrapper)(f) : f;
-}
-#else
-INLINE void SetIndirectCallWrapper(uptr wrapper) {}
-template <typename F>
-F IndirectExternCall(F f) {
- return f;
-}
-#endif
-
#if SANITIZER_ANDROID
// Initialize Android logging. Any writes before this are silently lost.
void AndroidLogInit();
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 4fb011156eb..274e87c3d67 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1442,30 +1442,30 @@ static THREADLOCAL __sanitizer_glob_t *pglob_copy;
static void wrapped_gl_closedir(void *dir) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
- IndirectExternCall(pglob_copy->gl_closedir)(dir);
+ pglob_copy->gl_closedir(dir);
}
static void *wrapped_gl_readdir(void *dir) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
- return IndirectExternCall(pglob_copy->gl_readdir)(dir);
+ return pglob_copy->gl_readdir(dir);
}
static void *wrapped_gl_opendir(const char *s) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
- return IndirectExternCall(pglob_copy->gl_opendir)(s);
+ return pglob_copy->gl_opendir(s);
}
static int wrapped_gl_lstat(const char *s, void *st) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
- return IndirectExternCall(pglob_copy->gl_lstat)(s, st);
+ return pglob_copy->gl_lstat(s, st);
}
static int wrapped_gl_stat(const char *s, void *st) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
- return IndirectExternCall(pglob_copy->gl_stat)(s, st);
+ return pglob_copy->gl_stat(s, st);
}
INTERCEPTOR(int, glob, const char *pattern, int flags,
@@ -2633,7 +2633,7 @@ static THREADLOCAL scandir_compar_f scandir_compar;
static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
- return IndirectExternCall(scandir_filter)(dir);
+ return scandir_filter(dir);
}
static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
@@ -2643,7 +2643,7 @@ static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
- return IndirectExternCall(scandir_compar)(a, b);
+ return scandir_compar(a, b);
}
INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
@@ -2685,7 +2685,7 @@ static THREADLOCAL scandir64_compar_f scandir64_compar;
static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
- return IndirectExternCall(scandir64_filter)(dir);
+ return scandir64_filter(dir);
}
static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
@@ -2695,7 +2695,7 @@ static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
- return IndirectExternCall(scandir64_compar)(a, b);
+ return scandir64_compar(a, b);
}
INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_interception.h b/compiler-rt/lib/sanitizer_common/sanitizer_interception.h
deleted file mode 100644
index b63462d2735..00000000000
--- a/compiler-rt/lib/sanitizer_common/sanitizer_interception.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//===-- sanitizer_interception.h --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Common macro definitions for interceptors.
-// Always use this headers instead of interception/interception.h.
-//
-//===----------------------------------------------------------------------===//
-#ifndef SANITIZER_INTERCEPTION_H
-#define SANITIZER_INTERCEPTION_H
-
-#include "interception/interception.h"
-#include "sanitizer_common.h"
-
-#if SANITIZER_LINUX && !defined(SANITIZER_GO)
-#undef REAL
-#define REAL(x) IndirectExternCall(__interception::PTR_TO_REAL(x))
-#endif
-
-#endif // SANITIZER_INTERCEPTION_H
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index 33876809f9c..2ca55b48453 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -128,7 +128,7 @@ bool SetEnv(const char *name, const char *value) {
setenv_ft setenv_f;
CHECK_EQ(sizeof(setenv_f), sizeof(f));
internal_memcpy(&setenv_f, &f, sizeof(f));
- return IndirectExternCall(setenv_f)(name, value, 1) == 0;
+ return setenv_f(name, value, 1) == 0;
}
bool SanitizerSetThreadName(const char *name) {
@@ -173,7 +173,7 @@ void InitTlsSize() {
CHECK_NE(get_tls, 0);
size_t tls_size = 0;
size_t tls_align = 0;
- IndirectExternCall(get_tls)(&tls_size, &tls_align);
+ get_tls(&tls_size, &tls_align);
g_tls_size = tls_size;
#endif // !SANITIZER_FREEBSD && !SANITIZER_ANDROID
}
@@ -408,14 +408,6 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
}
#endif // SANITIZER_ANDROID
-uptr indirect_call_wrapper;
-
-void SetIndirectCallWrapper(uptr wrapper) {
- CHECK(!indirect_call_wrapper);
- CHECK(wrapper);
- indirect_call_wrapper = wrapper;
-}
-
void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
// Some kinds of sandboxes may forbid filesystem access, so we won't be able
// to read the file mappings from /proc/self/maps. Luckily, neither the
diff --git a/compiler-rt/test/msan/wrap_indirect_calls.cc b/compiler-rt/test/msan/wrap_indirect_calls.cc
deleted file mode 100644
index be17bd824ec..00000000000
--- a/compiler-rt/test/msan/wrap_indirect_calls.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Test indirect call wrapping in MemorySanitizer.
-
-// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/two.cc -fPIC -shared -o %t-two-so.so
-// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/wrapper.cc -fPIC -shared -o %t-wrapper-so.so
-
-// Disable fast path.
-
-// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc %s \
-// RUN: %t-two-so.so %t-wrapper-so.so \
-// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
-// RUN: -mllvm -msan-wrap-indirect-calls-fast=0 \
-// RUN: -DSLOW=1 \
-// RUN: -Wl,--defsym=__executable_start=0 -o %t
-// RUN: %run %t
-
-// Enable fast path, call from executable, -O0.
-
-// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc %s \
-// RUN: %t-two-so.so %t-wrapper-so.so \
-// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
-// RUN: -mllvm -msan-wrap-indirect-calls-fast=1 \
-// RUN: -DSLOW=0 \
-// RUN: -Wl,--defsym=__executable_start=0 -o %t
-// RUN: %run %t
-
-// Enable fast path, call from executable, -O3.
-
-// RUN: %clangxx_msan -O3 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc %s \
-// RUN: %t-two-so.so %t-wrapper-so.so \
-// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
-// RUN: -mllvm -msan-wrap-indirect-calls-fast=1 \
-// RUN: -DSLOW=0 \
-// RUN: -Wl,--defsym=__executable_start=0 -o %t
-// RUN: %run %t
-
-// Enable fast path, call from DSO, -O0.
-
-// RUN: %clangxx_msan -O0 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc -shared \
-// RUN: %t-two-so.so %t-wrapper-so.so \
-// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
-// RUN: -mllvm -msan-wrap-indirect-calls-fast=1 \
-// RUN: -DSLOW=0 \
-// RUN: -Wl,--defsym=__executable_start=0 -o %t-caller-so.so
-// RUN: %clangxx_msan -O0 %s %t-caller-so.so %t-two-so.so %t-wrapper-so.so -o %t
-// RUN: %run %t
-
-// Enable fast path, call from DSO, -O3.
-
-// RUN: %clangxx_msan -O3 %p/wrap_indirect_calls/caller.cc %p/wrap_indirect_calls/one.cc -shared \
-// RUN: %t-two-so.so %t-wrapper-so.so \
-// RUN: -mllvm -msan-wrap-indirect-calls=wrapper \
-// RUN: -mllvm -msan-wrap-indirect-calls-fast=1 \
-// RUN: -DSLOW=0 \
-// RUN: -Wl,--defsym=__executable_start=0 -o %t-caller-so.so
-// RUN: %clangxx_msan -O3 %s %t-caller-so.so %t-two-so.so %t-wrapper-so.so -o %t
-// RUN: %run %t
-
-// The actual test is in multiple files in wrap_indirect_calls/ directory.
-void run_test();
-
-int main() {
- run_test();
- return 0;
-}
diff --git a/compiler-rt/test/msan/wrap_indirect_calls/caller.cc b/compiler-rt/test/msan/wrap_indirect_calls/caller.cc
deleted file mode 100644
index a0af8b7bb0c..00000000000
--- a/compiler-rt/test/msan/wrap_indirect_calls/caller.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Indirectly call a bunch of functions.
-
-#include <assert.h>
-
-extern int cnt;
-
-typedef int (*F)(int, int);
-
-// A function in the same object.
-int f_local(int x, int y) {
- return x + y;
-}
-
-// A function in another object.
-int f_other_object(int x, int y);
-
-// A function in another DSO.
-int f_dso(int x, int y);
-
-// A function in another DSO that is replaced by the wrapper.
-int f_replaced(int x, int y);
-
-void run_test(void) {
- int x;
- int expected_cnt = 0;
- volatile F f;
-
- if (SLOW) ++expected_cnt;
- f = &f_local;
- x = f(1, 2);
- assert(x == 3);
- assert(cnt == expected_cnt);
-
- if (SLOW) ++expected_cnt;
- f = &f_other_object;
- x = f(2, 3);
- assert(x == 6);
- assert(cnt == expected_cnt);
-
- ++expected_cnt;
- f = &f_dso;
- x = f(2, 3);
- assert(x == 7);
- assert(cnt == expected_cnt);
-
- ++expected_cnt;
- f = &f_replaced;
- x = f(2, 3);
- assert(x == 11);
- assert(cnt == expected_cnt);
-}
diff --git a/compiler-rt/test/msan/wrap_indirect_calls/lit.local.cfg b/compiler-rt/test/msan/wrap_indirect_calls/lit.local.cfg
deleted file mode 100644
index 5e01230c098..00000000000
--- a/compiler-rt/test/msan/wrap_indirect_calls/lit.local.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-# Sources in this directory are used by tests in parent directory.
-
-config.suffixes = []
diff --git a/compiler-rt/test/msan/wrap_indirect_calls/one.cc b/compiler-rt/test/msan/wrap_indirect_calls/one.cc
deleted file mode 100644
index ab7bf4125c0..00000000000
--- a/compiler-rt/test/msan/wrap_indirect_calls/one.cc
+++ /dev/null
@@ -1,3 +0,0 @@
-int f_other_object(int x, int y) {
- return x * y;
-}
diff --git a/compiler-rt/test/msan/wrap_indirect_calls/two.cc b/compiler-rt/test/msan/wrap_indirect_calls/two.cc
deleted file mode 100644
index c939a993bc9..00000000000
--- a/compiler-rt/test/msan/wrap_indirect_calls/two.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-int f_dso(int x, int y) {
- return 2 * x + y;
-}
-
-int f_replaced(int x, int y) {
- return x + y + 5;
-}
-
-int f_replacement(int x, int y) {
- return x + y + 6;
-}
diff --git a/compiler-rt/test/msan/wrap_indirect_calls/wrapper.cc b/compiler-rt/test/msan/wrap_indirect_calls/wrapper.cc
deleted file mode 100644
index 8fcd0c635d9..00000000000
--- a/compiler-rt/test/msan/wrap_indirect_calls/wrapper.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-int f_replaced(int x, int y);
-int f_replacement(int x, int y);
-
-int cnt;
-
-extern "C" void *wrapper(void *p) {
- ++cnt;
- if (p == (void *)f_replaced)
- return (void *)f_replacement;
- return p;
-}
diff --git a/compiler-rt/test/msan/wrap_indirect_calls2.cc b/compiler-rt/test/msan/wrap_indirect_calls2.cc
deleted file mode 100644
index fb4e6c798d6..00000000000
--- a/compiler-rt/test/msan/wrap_indirect_calls2.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Test __msan_set_indirect_call_wrapper.
-
-// RUN: %clangxx_msan -mllvm -msan-wrap-indirect-calls=__msan_wrap_indirect_call \
-// RUN: -mllvm -msan-wrap-indirect-calls-fast=0 \
-// RUN: -O0 -g -rdynamic -Wl,--defsym=__executable_start=0 %s -o %t && %run %t
-
-// This test disables -msan-wrap-indirect-calls-fast, otherwise indirect calls
-// inside the same module are short-circuited and are never seen by the wrapper.
-
-#include <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdint.h>
-
-extern "C" void __msan_set_indirect_call_wrapper(uintptr_t);
-
-bool done_f, done_g;
-
-void f(void) {
- assert(!done_g);
- done_f = true;
-}
-
-void g(void) {
- assert(done_f);
- done_g = true;
-}
-
-typedef void (*Fn)(void);
-extern "C" Fn my_wrapper(Fn target) {
- if (target == f) return g;
- return target;
-}
-
-int main(void) {
- volatile Fn fp;
- fp = &f;
- fp();
- __msan_set_indirect_call_wrapper((uintptr_t)my_wrapper);
- fp();
- return !(done_f && done_g);
-}
diff --git a/compiler-rt/test/msan/wrap_indirect_calls_in_rtl.cc b/compiler-rt/test/msan/wrap_indirect_calls_in_rtl.cc
deleted file mode 100644
index 58e80045e7d..00000000000
--- a/compiler-rt/test/msan/wrap_indirect_calls_in_rtl.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Test indirect call wrapping in MemorySanitizer runtime.
-
-// RUN: %clangxx_msan -O0 -g -rdynamic %s -o %t && %run %t
-// RUN: %clangxx_msan -O2 -g -rdynamic %s -o %t && %run %t
-
-#include <assert.h>
-#include <dlfcn.h>
-#include <math.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/time.h>
-
-extern "C" void __msan_set_indirect_call_wrapper(uintptr_t);
-
-bool pthread_create_done;
-
-void *ThreadFn(void *) {
- printf("bad threadfn\n");
- return 0;
-}
-
-void *ThreadFn2(void *) {
- printf("good threadfn\n");
- pthread_create_done = true;
- return 0;
-}
-
-int my_gettimeofday(struct timeval *p, void *q) {
- p->tv_sec = 1;
- p->tv_usec = 2;
- return 42;
-}
-
-double my_lgamma(double x) {
- return x;
-}
-
-uintptr_t real_gettimeofday;
-uintptr_t real_lgamma;
-
-extern "C" uintptr_t my_wrapper(uintptr_t f) {
- if (f == (uintptr_t)ThreadFn) return (uintptr_t)&ThreadFn2;
- if (f == real_gettimeofday) return (uintptr_t)my_gettimeofday;
- if (f == real_lgamma) return (uintptr_t)my_lgamma;
- return f;
-}
-
-int main(void) {
- real_gettimeofday = (uintptr_t)dlsym(RTLD_NEXT, "gettimeofday");
- real_lgamma = (uintptr_t)dlsym(RTLD_NEXT, "lgamma");
-
- __msan_set_indirect_call_wrapper((uintptr_t)my_wrapper);
-
- // ThreadFn is called indirectly from a wrapper function in MSan rtl and
- // is subject to indirect call wrapping (it could be an native-to-translated
- // edge).
- pthread_t t;
- pthread_create(&t, 0, ThreadFn, 0);
- pthread_join(t, 0);
- assert(pthread_create_done);
-
- // gettimeofday is intercepted in msan_interceptors.cc and the real one (from
- // libc) is called indirectly.
- struct timeval tv;
- int res = gettimeofday(&tv, NULL);
- assert(tv.tv_sec == 1);
- assert(tv.tv_usec == 2);
- assert(res == 42);
-
- // lgamma is intercepted in sanitizer_common_interceptors.inc and is also
- // called indirectly.
- double dres = lgamma(1.1);
- assert(dres == 1.1);
-
- return 0;
-}
OpenPOWER on IntegriCloud