[llvm-commits] [compiler-rt] r147784 - in /compiler-rt/trunk/lib/asan: asan_interceptors.cc asan_interceptors.h asan_internal.h asan_linux.cc asan_mac.cc asan_rtl.cc
Kostya Serebryany
kcc at google.com
Mon Jan 9 10:53:15 PST 2012
Author: kcc
Date: Mon Jan 9 12:53:15 2012
New Revision: 147784
URL: http://llvm.org/viewvc/llvm-project?rev=147784&view=rev
Log:
[asan] refactoring: move all interceptors to a single file
Modified:
compiler-rt/trunk/lib/asan/asan_interceptors.cc
compiler-rt/trunk/lib/asan/asan_interceptors.h
compiler-rt/trunk/lib/asan/asan_internal.h
compiler-rt/trunk/lib/asan/asan_linux.cc
compiler-rt/trunk/lib/asan/asan_mac.cc
compiler-rt/trunk/lib/asan/asan_rtl.cc
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=147784&r1=147783&r2=147784&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Mon Jan 9 12:53:15 2012
@@ -19,7 +19,9 @@
#include "asan_mapping.h"
#include "asan_stack.h"
#include "asan_stats.h"
+#include "asan_thread_registry.h"
+#include <new>
#include <ctype.h>
#include <dlfcn.h>
#include <string.h>
@@ -27,6 +29,29 @@
namespace __asan {
+typedef void (*longjmp_f)(void *env, int val);
+typedef longjmp_f _longjmp_f;
+typedef longjmp_f siglongjmp_f;
+typedef void (*__cxa_throw_f)(void *, void *, void *);
+typedef int (*pthread_create_f)(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine) (void *), void *arg);
+#ifdef __APPLE__
+dispatch_async_f_f real_dispatch_async_f;
+dispatch_sync_f_f real_dispatch_sync_f;
+dispatch_after_f_f real_dispatch_after_f;
+dispatch_barrier_async_f_f real_dispatch_barrier_async_f;
+dispatch_group_async_f_f real_dispatch_group_async_f;
+pthread_workqueue_additem_np_f real_pthread_workqueue_additem_np;
+#endif
+
+sigaction_f real_sigaction;
+signal_f real_signal;
+longjmp_f real_longjmp;
+_longjmp_f real__longjmp;
+siglongjmp_f real_siglongjmp;
+__cxa_throw_f real___cxa_throw;
+pthread_create_f real_pthread_create;
+
index_f real_index;
memcmp_f real_memcmp;
memcpy_f real_memcpy;
@@ -156,6 +181,32 @@
INTERCEPT_FUNCTION(strncasecmp);
INTERCEPT_FUNCTION(strncmp);
INTERCEPT_FUNCTION(strncpy);
+
+ INTERCEPT_FUNCTION(sigaction);
+ INTERCEPT_FUNCTION(signal);
+ INTERCEPT_FUNCTION(longjmp);
+ INTERCEPT_FUNCTION(_longjmp);
+ INTERCEPT_FUNCTION_IF_EXISTS(__cxa_throw);
+ INTERCEPT_FUNCTION(pthread_create);
+
+#ifdef __APPLE__
+ INTERCEPT_FUNCTION(dispatch_async_f);
+ INTERCEPT_FUNCTION(dispatch_sync_f);
+ INTERCEPT_FUNCTION(dispatch_after_f);
+ INTERCEPT_FUNCTION(dispatch_barrier_async_f);
+ INTERCEPT_FUNCTION(dispatch_group_async_f);
+ // We don't need to intercept pthread_workqueue_additem_np() to support the
+ // libdispatch API, but it helps us to debug the unsupported functions. Let's
+ // intercept it only during verbose runs.
+ if (FLAG_v >= 2) {
+ INTERCEPT_FUNCTION(pthread_workqueue_additem_np);
+ }
+#else
+ // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it
+ // there.
+ INTERCEPT_FUNCTION(siglongjmp);
+#endif
+
#ifndef __APPLE__
INTERCEPT_FUNCTION(strnlen);
#endif
@@ -169,6 +220,136 @@
// ---------------------- Wrappers ---------------- {{{1
using namespace __asan; // NOLINT
+#define OPERATOR_NEW_BODY \
+ GET_STACK_TRACE_HERE_FOR_MALLOC;\
+ return asan_memalign(0, size, &stack);
+
+#ifdef ANDROID
+void *operator new(size_t size) { OPERATOR_NEW_BODY; }
+void *operator new[](size_t size) { OPERATOR_NEW_BODY; }
+#else
+void *operator new(size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; }
+void *operator new[](size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; }
+void *operator new(size_t size, std::nothrow_t const&) throw()
+{ OPERATOR_NEW_BODY; }
+void *operator new[](size_t size, std::nothrow_t const&) throw()
+{ OPERATOR_NEW_BODY; }
+#endif
+
+#define OPERATOR_DELETE_BODY \
+ GET_STACK_TRACE_HERE_FOR_FREE(ptr);\
+ asan_free(ptr, &stack);
+
+void operator delete(void *ptr) throw() { OPERATOR_DELETE_BODY; }
+void operator delete[](void *ptr) throw() { OPERATOR_DELETE_BODY; }
+void operator delete(void *ptr, std::nothrow_t const&) throw()
+{ OPERATOR_DELETE_BODY; }
+void operator delete[](void *ptr, std::nothrow_t const&) throw()
+{ OPERATOR_DELETE_BODY;}
+
+static void *asan_thread_start(void *arg) {
+ AsanThread *t = (AsanThread*)arg;
+ asanThreadRegistry().SetCurrent(t);
+ return t->ThreadStart();
+}
+
+extern "C"
+#ifndef __APPLE__
+__attribute__((visibility("default")))
+#endif
+int WRAP(pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine) (void *), void *arg) {
+ GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false);
+ AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
+ CHECK(curr_thread || asanThreadRegistry().IsCurrentThreadDying());
+ int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
+ AsanThread *t = AsanThread::Create(current_tid, start_routine, arg);
+ asanThreadRegistry().RegisterThread(t, current_tid, &stack);
+ return real_pthread_create(thread, attr, asan_thread_start, t);
+}
+
+extern "C"
+void *WRAP(signal)(int signum, void *handler) {
+ if (!AsanInterceptsSignal(signum)) {
+ return real_signal(signum, handler);
+ }
+ return NULL;
+}
+
+extern "C"
+int WRAP(sigaction)(int signum, const struct sigaction *act,
+ struct sigaction *oldact) {
+ if (!AsanInterceptsSignal(signum)) {
+ return real_sigaction(signum, act, oldact);
+ }
+ return 0;
+}
+
+
+static void UnpoisonStackFromHereToTop() {
+ int local_stack;
+ AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
+ CHECK(curr_thread);
+ uintptr_t top = curr_thread->stack_top();
+ uintptr_t bottom = ((uintptr_t)&local_stack - kPageSize) & ~(kPageSize-1);
+ PoisonShadow(bottom, top - bottom, 0);
+}
+
+extern "C" void WRAP(longjmp)(void *env, int val) {
+ UnpoisonStackFromHereToTop();
+ real_longjmp(env, val);
+}
+
+extern "C" void WRAP(_longjmp)(void *env, int val) {
+ UnpoisonStackFromHereToTop();
+ real__longjmp(env, val);
+}
+
+extern "C" void WRAP(siglongjmp)(void *env, int val) {
+ UnpoisonStackFromHereToTop();
+ real_siglongjmp(env, val);
+}
+
+extern "C" void __cxa_throw(void *a, void *b, void *c);
+
+#if ASAN_HAS_EXCEPTIONS == 1
+extern "C" void WRAP(__cxa_throw)(void *a, void *b, void *c) {
+ CHECK(&real___cxa_throw);
+ UnpoisonStackFromHereToTop();
+ real___cxa_throw(a, b, c);
+}
+#endif
+
+extern "C" {
+// intercept mlock and friends.
+// Since asan maps 16T of RAM, mlock is completely unfriendly to asan.
+// All functions return 0 (success).
+static void MlockIsUnsupported() {
+ static bool printed = 0;
+ if (printed) return;
+ printed = true;
+ Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n");
+}
+int mlock(const void *addr, size_t len) {
+ MlockIsUnsupported();
+ return 0;
+}
+int munlock(const void *addr, size_t len) {
+ MlockIsUnsupported();
+ return 0;
+}
+int mlockall(int flags) {
+ MlockIsUnsupported();
+ return 0;
+}
+int munlockall(void) {
+ MlockIsUnsupported();
+ return 0;
+}
+} // extern "C"
+
+
+
static inline int CharCmp(unsigned char c1, unsigned char c2) {
return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
}
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.h?rev=147784&r1=147783&r2=147784&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.h Mon Jan 9 12:53:15 2012
@@ -101,6 +101,8 @@
typedef int (*strncmp_f)(const char *s1, const char *s2, size_t size);
typedef char* (*strncpy_f)(char *to, const char *from, size_t size);
typedef size_t (*strnlen_f)(const char *s, size_t maxlen);
+typedef void *(*signal_f)(int signum, void *handler);
+typedef int (*sigaction_f)(int signum, const void *act, void *oldact);
// __asan::real_X() holds pointer to library implementation of X().
extern index_f real_index;
@@ -119,6 +121,8 @@
extern strncmp_f real_strncmp;
extern strncpy_f real_strncpy;
extern strnlen_f real_strnlen;
+extern signal_f real_signal;
+extern sigaction_f real_sigaction;
// __asan::internal_X() is the implementation of X() for use in RTL.
size_t internal_strlen(const char *s);
Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=147784&r1=147783&r2=147784&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Mon Jan 9 12:53:15 2012
@@ -106,6 +106,8 @@
ssize_t AsanWrite(int fd, const void *buf, size_t count);
int AsanClose(int fd);
+bool AsanInterceptsSignal(int signum);
+
// Opens the file 'file_name" and reads up to 'max_len' bytes.
// The resulting buffer is mmaped and stored in '*buff'.
// The size of the mmaped region is stored in '*buff_size',
@@ -151,6 +153,7 @@
extern size_t FLAG_max_malloc_fill_size;
extern int FLAG_exitcode;
extern bool FLAG_allow_user_poisoning;
+extern bool FLAG_handle_segv;
extern int asan_inited;
// Used to avoid infinite recursion in __asan_init().
Modified: compiler-rt/trunk/lib/asan/asan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=147784&r1=147783&r2=147784&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Mon Jan 9 12:53:15 2012
@@ -64,6 +64,10 @@
#endif
}
+bool AsanInterceptsSignal(int signum) {
+ return signum == SIGSEGV && FLAG_handle_segv;
+}
+
static void *asan_mmap(void *addr, size_t length, int prot, int flags,
int fd, uint64_t offset) {
# if __WORDSIZE == 64
Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=147784&r1=147783&r2=147784&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Mon Jan 9 12:53:15 2012
@@ -56,6 +56,10 @@
return NULL;
}
+bool AsanInterceptsSignal(int signum) {
+ return (signum == SIGSEGV || signum == SIGBUS) && FLAG_handle_segv;
+}
+
static void *asan_mmap(void *addr, size_t length, int prot, int flags,
int fd, uint64_t offset) {
return mmap(addr, length, prot, flags, fd, offset);
Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=147784&r1=147783&r2=147784&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Mon Jan 9 12:53:15 2012
@@ -24,19 +24,9 @@
#include "asan_thread.h"
#include "asan_thread_registry.h"
-#include <new>
-#include <dlfcn.h>
-#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-// must not include <setjmp.h> on Linux
namespace __asan {
@@ -69,33 +59,6 @@
int asan_inited;
bool asan_init_is_running;
-// -------------------------- Interceptors ---------------- {{{1
-typedef int (*sigaction_f)(int signum, const struct sigaction *act,
- struct sigaction *oldact);
-typedef sig_t (*signal_f)(int signum, sig_t handler);
-typedef void (*longjmp_f)(void *env, int val);
-typedef longjmp_f _longjmp_f;
-typedef longjmp_f siglongjmp_f;
-typedef void (*__cxa_throw_f)(void *, void *, void *);
-typedef int (*pthread_create_f)(pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine) (void *), void *arg);
-#ifdef __APPLE__
-dispatch_async_f_f real_dispatch_async_f;
-dispatch_sync_f_f real_dispatch_sync_f;
-dispatch_after_f_f real_dispatch_after_f;
-dispatch_barrier_async_f_f real_dispatch_barrier_async_f;
-dispatch_group_async_f_f real_dispatch_group_async_f;
-pthread_workqueue_additem_np_f real_pthread_workqueue_additem_np;
-#endif
-
-sigaction_f real_sigaction;
-signal_f real_signal;
-longjmp_f real_longjmp;
-_longjmp_f real__longjmp;
-siglongjmp_f real_siglongjmp;
-__cxa_throw_f real___cxa_throw;
-pthread_create_f real_pthread_create;
-
// -------------------------- Misc ---------------- {{{1
void ShowStatsAndAbort() {
__asan_print_accumulated_stats();
@@ -161,11 +124,15 @@
return NULL; // Not found.
}
-// ---------------------- Thread ------------------------- {{{1
-static void *asan_thread_start(void *arg) {
- AsanThread *t= (AsanThread*)arg;
- asanThreadRegistry().SetCurrent(t);
- return t->ThreadStart();
+static void MaybeInstallSigaction(int signum,
+ void (*handler)(int, siginfo_t *, void *)) {
+ if (!AsanInterceptsSignal(signum))
+ return;
+ struct sigaction sigact;
+ real_memset(&sigact, 0, sizeof(sigact));
+ sigact.sa_sigaction = handler;
+ sigact.sa_flags = SA_SIGINFO;
+ CHECK(0 == real_sigaction(signum, &sigact, 0));
}
// ---------------------- mmap -------------------- {{{1
@@ -359,151 +326,9 @@
} // namespace __asan
-// -------------------------- Interceptors ------------------- {{{1
+// ---------------------- Interface ---------------- {{{1
using namespace __asan; // NOLINT
-#define OPERATOR_NEW_BODY \
- GET_STACK_TRACE_HERE_FOR_MALLOC;\
- return asan_memalign(0, size, &stack);
-
-#ifdef ANDROID
-void *operator new(size_t size) { OPERATOR_NEW_BODY; }
-void *operator new[](size_t size) { OPERATOR_NEW_BODY; }
-#else
-void *operator new(size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; }
-void *operator new[](size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; }
-void *operator new(size_t size, std::nothrow_t const&) throw()
-{ OPERATOR_NEW_BODY; }
-void *operator new[](size_t size, std::nothrow_t const&) throw()
-{ OPERATOR_NEW_BODY; }
-#endif
-
-#define OPERATOR_DELETE_BODY \
- GET_STACK_TRACE_HERE_FOR_FREE(ptr);\
- asan_free(ptr, &stack);
-
-void operator delete(void *ptr) throw() { OPERATOR_DELETE_BODY; }
-void operator delete[](void *ptr) throw() { OPERATOR_DELETE_BODY; }
-void operator delete(void *ptr, std::nothrow_t const&) throw()
-{ OPERATOR_DELETE_BODY; }
-void operator delete[](void *ptr, std::nothrow_t const&) throw()
-{ OPERATOR_DELETE_BODY;}
-
-extern "C"
-#ifndef __APPLE__
-__attribute__((visibility("default")))
-#endif
-int WRAP(pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine) (void *), void *arg) {
- GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false);
- AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
- CHECK(curr_thread || asanThreadRegistry().IsCurrentThreadDying());
- int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
- AsanThread *t = AsanThread::Create(current_tid, start_routine, arg);
- asanThreadRegistry().RegisterThread(t, current_tid, &stack);
- return real_pthread_create(thread, attr, asan_thread_start, t);
-}
-
-static bool MySignal(int signum) {
- if (FLAG_handle_segv && signum == SIGSEGV) return true;
-#ifdef __APPLE__
- if (FLAG_handle_segv && signum == SIGBUS) return true;
-#endif
- return false;
-}
-
-static void MaybeInstallSigaction(int signum,
- void (*handler)(int, siginfo_t *, void *)) {
- if (!MySignal(signum))
- return;
- struct sigaction sigact;
- real_memset(&sigact, 0, sizeof(sigact));
- sigact.sa_sigaction = handler;
- sigact.sa_flags = SA_SIGINFO;
- CHECK(0 == real_sigaction(signum, &sigact, 0));
-}
-
-extern "C"
-sig_t WRAP(signal)(int signum, sig_t handler) {
- if (!MySignal(signum)) {
- return real_signal(signum, handler);
- }
- return NULL;
-}
-
-extern "C"
-int WRAP(sigaction)(int signum, const struct sigaction *act,
- struct sigaction *oldact) {
- if (!MySignal(signum)) {
- return real_sigaction(signum, act, oldact);
- }
- return 0;
-}
-
-
-static void UnpoisonStackFromHereToTop() {
- int local_stack;
- AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
- CHECK(curr_thread);
- uintptr_t top = curr_thread->stack_top();
- uintptr_t bottom = ((uintptr_t)&local_stack - kPageSize) & ~(kPageSize-1);
- PoisonShadow(bottom, top - bottom, 0);
-}
-
-extern "C" void WRAP(longjmp)(void *env, int val) {
- UnpoisonStackFromHereToTop();
- real_longjmp(env, val);
-}
-
-extern "C" void WRAP(_longjmp)(void *env, int val) {
- UnpoisonStackFromHereToTop();
- real__longjmp(env, val);
-}
-
-extern "C" void WRAP(siglongjmp)(void *env, int val) {
- UnpoisonStackFromHereToTop();
- real_siglongjmp(env, val);
-}
-
-extern "C" void __cxa_throw(void *a, void *b, void *c);
-
-#if ASAN_HAS_EXCEPTIONS == 1
-extern "C" void WRAP(__cxa_throw)(void *a, void *b, void *c) {
- CHECK(&real___cxa_throw);
- UnpoisonStackFromHereToTop();
- real___cxa_throw(a, b, c);
-}
-#endif
-
-extern "C" {
-// intercept mlock and friends.
-// Since asan maps 16T of RAM, mlock is completely unfriendly to asan.
-// All functions return 0 (success).
-static void MlockIsUnsupported() {
- static bool printed = 0;
- if (printed) return;
- printed = true;
- Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n");
-}
-int mlock(const void *addr, size_t len) {
- MlockIsUnsupported();
- return 0;
-}
-int munlock(const void *addr, size_t len) {
- MlockIsUnsupported();
- return 0;
-}
-int mlockall(int flags) {
- MlockIsUnsupported();
- return 0;
-}
-int munlockall(void) {
- MlockIsUnsupported();
- return 0;
-}
-} // extern "C"
-
-// ---------------------- Interface ---------------- {{{1
int __asan_set_error_exit_code(int exit_code) {
int old = FLAG_exitcode;
FLAG_exitcode = exit_code;
@@ -655,30 +480,6 @@
ReplaceSystemMalloc();
- INTERCEPT_FUNCTION(sigaction);
- INTERCEPT_FUNCTION(signal);
- INTERCEPT_FUNCTION(longjmp);
- INTERCEPT_FUNCTION(_longjmp);
- INTERCEPT_FUNCTION_IF_EXISTS(__cxa_throw);
- INTERCEPT_FUNCTION(pthread_create);
-#ifdef __APPLE__
- INTERCEPT_FUNCTION(dispatch_async_f);
- INTERCEPT_FUNCTION(dispatch_sync_f);
- INTERCEPT_FUNCTION(dispatch_after_f);
- INTERCEPT_FUNCTION(dispatch_barrier_async_f);
- INTERCEPT_FUNCTION(dispatch_group_async_f);
- // We don't need to intercept pthread_workqueue_additem_np() to support the
- // libdispatch API, but it helps us to debug the unsupported functions. Let's
- // intercept it only during verbose runs.
- if (FLAG_v >= 2) {
- INTERCEPT_FUNCTION(pthread_workqueue_additem_np);
- }
-#else
- // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it
- // there.
- INTERCEPT_FUNCTION(siglongjmp);
-#endif
-
MaybeInstallSigaction(SIGSEGV, ASAN_OnSIGSEGV);
MaybeInstallSigaction(SIGBUS, ASAN_OnSIGSEGV);
More information about the llvm-commits
mailing list