summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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