forked from OSchip/llvm-project
[msan] Replace wrap_indirect_calls runtime flag with an interface method.
llvm-svn: 197799
This commit is contained in:
parent
18f666b524
commit
61628196e4
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ struct Flags {
|
|||
bool report_umrs;
|
||||
bool wrap_signals;
|
||||
bool halt_on_error;
|
||||
const char *wrap_indirect_calls;
|
||||
};
|
||||
|
||||
Flags *flags();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue