[msan] Replace wrap_indirect_calls runtime flag with an interface method.

llvm-svn: 197799
This commit is contained in:
Evgeniy Stepanov 2013-12-20 11:05:19 +00:00
parent 18f666b524
commit 61628196e4
7 changed files with 73 additions and 20 deletions

View File

@ -0,0 +1,42 @@
// 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 && %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);
}

View File

@ -1,13 +1,14 @@
// Test indirect call wrapping in MemorySanitizer runtime.
// RUN: %clangxx_msan -O0 -g -rdynamic %s -o %t
// RUN: MSAN_OPTIONS=wrap_indirect_calls=zzzwrapper %t
// RUN: %clangxx_msan -O0 -g -rdynamic %s -o %t && %t
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
extern "C" void __msan_set_indirect_call_wrapper(uintptr_t);
bool done;
void *ThreadFn(void *) {
@ -24,13 +25,14 @@ void *ThreadFn2(void *) {
// 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).
extern "C" uintptr_t zzzwrapper(uintptr_t f) {
extern "C" uintptr_t my_wrapper(uintptr_t f) {
if (f == (uintptr_t)ThreadFn)
return (uintptr_t)&ThreadFn2;
return f;
}
int main(void) {
__msan_set_indirect_call_wrapper((uintptr_t)my_wrapper);
pthread_t t;
pthread_create(&t, 0, ThreadFn, 0);
pthread_join(t, 0);

View File

@ -31,7 +31,7 @@ using namespace __sanitizer;
static THREADLOCAL int msan_expect_umr = 0;
static THREADLOCAL int msan_expected_umr_found = 0;
static int msan_running_under_dr = 0;
static bool msan_running_under_dr;
// Function argument shadow. Each argument starts at the next available 8-byte
// aligned address.
@ -74,10 +74,6 @@ extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going;
namespace __msan {
static bool IsRunningUnderDr() {
return false;
}
void EnterSymbolizer() { ++is_in_symbolizer; }
void ExitSymbolizer() { --is_in_symbolizer; }
bool IsInSymbolizer() { return is_in_symbolizer; }
@ -122,7 +118,6 @@ static void ParseFlagsFromString(Flags *f, const char *str) {
}
ParseFlag(str, &f->report_umrs, "report_umrs");
ParseFlag(str, &f->wrap_signals, "wrap_signals");
ParseFlag(str, &f->wrap_indirect_calls, "wrap_indirect_calls");
// keep_going is an old name for halt_on_error,
// and it has inverse meaning.
@ -147,7 +142,6 @@ static void InitializeFlags(Flags *f, const char *options) {
f->exit_code = 77;
f->report_umrs = true;
f->wrap_signals = true;
f->wrap_indirect_calls = "dr_app_handle_mbr_target";
f->halt_on_error = !&__msan_keep_going;
// Override from user-specified string.
@ -292,7 +286,6 @@ void __msan_init() {
VPrintf(1, "MSAN_OPTIONS: %s\n", msan_options ? msan_options : "<empty>");
msan_running_under_dr = IsRunningUnderDr();
__msan_clear_on_return();
if (__msan_get_track_origins())
VPrintf(1, "msan_track_origins\n");
@ -324,8 +317,6 @@ void __msan_init() {
msan_init_is_running = 0;
msan_inited = 1;
InitializeIndirectCallWrapping(flags()->wrap_indirect_calls);
}
void __msan_set_exit_code(int exit_code) {
@ -542,10 +533,21 @@ void __sanitizer_unaligned_store64(uu64 *p, u64 x) {
*p = x;
}
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
const char* __msan_default_options() { return ""; }
} // extern "C"
#endif

View File

@ -26,7 +26,6 @@ struct Flags {
bool report_umrs;
bool wrap_signals;
bool halt_on_error;
const char *wrap_indirect_calls;
};
Flags *flags();

View File

@ -170,6 +170,15 @@ SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
/* OPTIONAL */ void __msan_free_hook(void *ptr);
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);
} // extern "C"
#endif // MSAN_INTERFACE_INTERNAL_H

View File

@ -487,7 +487,7 @@ typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
#if SANITIZER_LINUX && !defined(SANITIZER_GO)
extern uptr indirect_call_wrapper;
void InitializeIndirectCallWrapping(const char *wrapper_name);
void SetIndirectCallWrapper(uptr wrapper);
template <typename F>
F IndirectExternCall(F f) {
@ -495,7 +495,7 @@ F IndirectExternCall(F f) {
return indirect_call_wrapper ? ((WrapF)indirect_call_wrapper)(f) : f;
}
#else
inline void InitializeIndirectCallWrapping(const char *wrapper_name) {}
inline void SetIndirectCallWrapper(uptr wrapper) {}
template <typename F>
F IndirectExternCall(F f) {
return f;

View File

@ -356,9 +356,8 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules,
#ifndef SANITIZER_GO
uptr indirect_call_wrapper;
void InitializeIndirectCallWrapping(const char *wrapper_name) {
CHECK(wrapper_name && *wrapper_name);
indirect_call_wrapper = (uptr)dlsym(RTLD_DEFAULT, wrapper_name);
void SetIndirectCallWrapper(uptr wrapper) {
indirect_call_wrapper = wrapper;
}
#endif