[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