summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/asan/asan_interceptors.cc28
-rw-r--r--compiler-rt/lib/asan/asan_internal.h7
-rw-r--r--compiler-rt/lib/asan/asan_thread.cc6
-rw-r--r--compiler-rt/lib/asan/asan_thread.h6
-rw-r--r--compiler-rt/lib/asan/asan_win.cc2
-rw-r--r--compiler-rt/lib/asan/interception/interception.h31
6 files changed, 64 insertions, 16 deletions
diff --git a/compiler-rt/lib/asan/asan_interceptors.cc b/compiler-rt/lib/asan/asan_interceptors.cc
index cd824452ff3..1d85facd754 100644
--- a/compiler-rt/lib/asan/asan_interceptors.cc
+++ b/compiler-rt/lib/asan/asan_interceptors.cc
@@ -254,7 +254,7 @@ void operator delete(void *ptr, std::nothrow_t const&) throw()
void operator delete[](void *ptr, std::nothrow_t const&) throw()
{ OPERATOR_DELETE_BODY;}
-static void *asan_thread_start(void *arg) {
+static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
AsanThread *t = (AsanThread*)arg;
asanThreadRegistry().SetCurrent(t);
return t->ThreadStart();
@@ -579,6 +579,27 @@ INTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) {
}
#endif
+#if defined(_WIN32)
+INTERCEPTOR_WINAPI(DWORD, CreateThread,
+ void* security, size_t stack_size,
+ DWORD (__stdcall *start_routine)(void*), void* arg,
+ DWORD flags, void* tid) {
+ GET_STACK_TRACE_HERE(kStackTraceMax);
+ int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
+ AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
+ asanThreadRegistry().RegisterThread(t);
+ return REAL(CreateThread)(security, stack_size,
+ asan_thread_start, t, flags, tid);
+}
+
+namespace __asan {
+void InitializeWindowsInterceptors() {
+ CHECK(INTERCEPT_FUNCTION(CreateThread));
+}
+
+} // namespace __asan
+#endif
+
// ---------------------- InitializeAsanInterceptors ---------------- {{{1
namespace __asan {
void InitializeAsanInterceptors() {
@@ -654,6 +675,11 @@ void InitializeAsanInterceptors() {
# endif
#endif
+ // Some Windows-specific interceptors.
+#if defined(_WIN32)
+ InitializeWindowsInterceptors();
+#endif
+
// Some Mac-specific interceptors.
#if defined(__APPLE__)
CHECK(INTERCEPT_FUNCTION(dispatch_async_f));
diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h
index a3c6b383f41..fde24d597a8 100644
--- a/compiler-rt/lib/asan/asan_internal.h
+++ b/compiler-rt/lib/asan/asan_internal.h
@@ -30,6 +30,7 @@ typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
+typedef unsigned long DWORD; // NOLINT
extern "C" void* _ReturnAddress(void);
# pragma intrinsic(_ReturnAddress)
@@ -265,6 +266,8 @@ const size_t kPageSize = 1UL << kPageSizeBits;
const size_t kMmapGranularity = kPageSize;
# define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0)
# define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0)
+# define THREAD_CALLING_CONV
+typedef void* thread_return_t;
#else
const size_t kMmapGranularity = 1UL << 16;
# define GET_CALLER_PC() (uintptr_t)_ReturnAddress()
@@ -272,6 +275,8 @@ const size_t kMmapGranularity = 1UL << 16;
// FIXME: This macro is still used when printing error reports though it's not
// clear if the BP value is needed in the ASan reports on Windows.
# define GET_CURRENT_FRAME() (uintptr_t)0xDEADBEEF
+# define THREAD_CALLING_CONV __stdcall
+typedef DWORD thread_return_t;
# ifndef ASAN_USE_EXTERNAL_SYMBOLIZER
# define ASAN_USE_EXTERNAL_SYMBOLIZER __asan::WinSymbolize
@@ -279,6 +284,8 @@ bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size);
# endif
#endif
+typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg);
+
#define GET_BP_PC_SP \
uintptr_t bp = GET_CURRENT_FRAME(); \
uintptr_t pc = GET_CALLER_PC(); \
diff --git a/compiler-rt/lib/asan/asan_thread.cc b/compiler-rt/lib/asan/asan_thread.cc
index 6e6436b8144..c829292d008 100644
--- a/compiler-rt/lib/asan/asan_thread.cc
+++ b/compiler-rt/lib/asan/asan_thread.cc
@@ -26,7 +26,7 @@ AsanThread::AsanThread(LinkerInitialized x)
malloc_storage_(x),
stats_(x) { }
-AsanThread *AsanThread::Create(int parent_tid, void *(*start_routine) (void *),
+AsanThread *AsanThread::Create(int parent_tid, thread_callback_t start_routine,
void *arg, AsanStackTrace *stack) {
size_t size = RoundUpTo(sizeof(AsanThread), kPageSize);
AsanThread *thread = (AsanThread*)AsanMmapSomewhereOrDie(size, __FUNCTION__);
@@ -80,7 +80,7 @@ void AsanThread::Init() {
fake_stack_.Init(stack_size());
}
-void *AsanThread::ThreadStart() {
+thread_return_t AsanThread::ThreadStart() {
Init();
if (!start_routine_) {
@@ -91,7 +91,7 @@ void *AsanThread::ThreadStart() {
return 0;
}
- void *res = start_routine_(arg_);
+ thread_return_t res = start_routine_(arg_);
malloc_storage().CommitBack();
this->Destroy();
diff --git a/compiler-rt/lib/asan/asan_thread.h b/compiler-rt/lib/asan/asan_thread.h
index 9fc1e26ca6b..09607d91d6e 100644
--- a/compiler-rt/lib/asan/asan_thread.h
+++ b/compiler-rt/lib/asan/asan_thread.h
@@ -65,12 +65,12 @@ class AsanThreadSummary {
class AsanThread {
public:
explicit AsanThread(LinkerInitialized); // for T0.
- static AsanThread *Create(int parent_tid, void *(*start_routine) (void *),
+ static AsanThread *Create(int parent_tid, thread_callback_t start_routine,
void *arg, AsanStackTrace *stack);
void Destroy();
void Init(); // Should be called from the thread itself.
- void *ThreadStart();
+ thread_return_t ThreadStart();
uintptr_t stack_top() { return stack_top_; }
uintptr_t stack_bottom() { return stack_bottom_; }
@@ -96,7 +96,7 @@ class AsanThread {
void SetThreadStackTopAndBottom();
void ClearShadowForThreadStack();
AsanThreadSummary *summary_;
- void *(*start_routine_) (void *param);
+ thread_callback_t start_routine_;
void *arg_;
uintptr_t stack_top_;
uintptr_t stack_bottom_;
diff --git a/compiler-rt/lib/asan/asan_win.cc b/compiler-rt/lib/asan/asan_win.cc
index 2692b0db5b7..d47ff08e9e0 100644
--- a/compiler-rt/lib/asan/asan_win.cc
+++ b/compiler-rt/lib/asan/asan_win.cc
@@ -47,7 +47,7 @@ void *AsanMprotect(uintptr_t fixed_addr, size_t size) {
}
void AsanUnmapOrDie(void *addr, size_t size) {
- UNIMPLEMENTED();
+ CHECK(VirtualFree(addr, size, MEM_DECOMMIT));
}
// ---------------------- IO ---------------- {{{1
diff --git a/compiler-rt/lib/asan/interception/interception.h b/compiler-rt/lib/asan/interception/interception.h
index ae56af32f0e..50c03bb1708 100644
--- a/compiler-rt/lib/asan/interception/interception.h
+++ b/compiler-rt/lib/asan/interception/interception.h
@@ -100,21 +100,37 @@
DECLARE_REAL(ret_type, func, ##__VA_ARGS__); \
extern "C" ret_type WRAP(func)(__VA_ARGS__);
+// FIXME(timurrrr): We might need to add DECLARE_REAL_EX etc to support
+// different calling conventions later.
+
+#define DEFINE_REAL_EX(ret_type, convention, func, ...); \
+ typedef ret_type (convention *FUNC_TYPE(func))(__VA_ARGS__); \
+ namespace __interception { \
+ FUNC_TYPE(func) PTR_TO_REAL(func); \
+ }
+
// Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR
// macros does its job. In exceptional cases you may need to call REAL(foo)
// without defining INTERCEPTOR(..., foo, ...). For example, if you override
// foo with an interceptor for other function.
+#define DEFAULT_CONVENTION
+
#define DEFINE_REAL(ret_type, func, ...); \
- typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
- namespace __interception { \
- FUNC_TYPE(func) PTR_TO_REAL(func); \
- }
+ DEFINE_REAL_EX(ret_type, DEFAULT_CONVENTION, func, __VA_ARGS__);
-#define INTERCEPTOR(ret_type, func, ...) \
- DEFINE_REAL(ret_type, func, __VA_ARGS__); \
+#define INTERCEPTOR_EX(ret_type, convention, func, ...) \
+ DEFINE_REAL_EX(ret_type, convention, func, __VA_ARGS__); \
extern "C" \
INTERCEPTOR_ATTRIBUTE \
- ret_type WRAP(func)(__VA_ARGS__)
+ ret_type convention WRAP(func)(__VA_ARGS__)
+
+#define INTERCEPTOR(ret_type, func, ...) \
+ INTERCEPTOR_EX(ret_type, DEFAULT_CONVENTION, func, __VA_ARGS__)
+
+#if defined(_WIN32)
+# define INTERCEPTOR_WINAPI(ret_type, func, ...) \
+ INTERCEPTOR_EX(ret_type, __stdcall, func, __VA_ARGS__)
+#endif
#define INCLUDED_FROM_INTERCEPTION_LIB
@@ -127,7 +143,6 @@
OVERRIDE_FUNCTION_MAC(old_func, new_func)
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func)
#else // defined(_WIN32)
- // FIXME: deal with interception on Win.
# include "interception_win.h"
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_WIN(func)
#endif
OpenPOWER on IntegriCloud