aboutsummaryrefslogtreecommitdiff
path: root/lib/asan/asan_linux.cc
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2013-01-18 20:06:45 +0000
committerAndrew Turner <andrew@FreeBSD.org>2013-01-18 20:06:45 +0000
commit58aabf08b77d221489f10e274812ec60917c21a8 (patch)
treeb946f82269be87d83f086167c762c362e734c5bb /lib/asan/asan_linux.cc
parent37dfff057418e02f8e5322da12684dd927e3d881 (diff)
downloadsrc-58aabf08b77d221489f10e274812ec60917c21a8.tar.gz
src-58aabf08b77d221489f10e274812ec60917c21a8.zip
Import compiler-rt r172839.vendor/compiler-rt/compiler-rt-r172839
Notes
Notes: svn path=/vendor/compiler-rt/dist/; revision=245614 svn path=/vendor/compiler-rt/compiler-rt-r172839/; revision=245615; tag=vendor/compiler-rt/compiler-rt-r172839
Diffstat (limited to 'lib/asan/asan_linux.cc')
-rw-r--r--lib/asan/asan_linux.cc111
1 files changed, 51 insertions, 60 deletions
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc
index 9a3d6bdb15a6..845493de0956 100644
--- a/lib/asan/asan_linux.cc
+++ b/lib/asan/asan_linux.cc
@@ -15,8 +15,8 @@
#include "asan_interceptors.h"
#include "asan_internal.h"
-#include "asan_lock.h"
#include "asan_thread.h"
+#include "asan_thread_registry.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_procmaps.h"
@@ -31,7 +31,7 @@
#include <unistd.h>
#include <unwind.h>
-#ifndef ANDROID
+#if !ASAN_ANDROID
// FIXME: where to get ucontext on Android?
#include <sys/ucontext.h>
#endif
@@ -40,13 +40,17 @@ extern "C" void* _DYNAMIC;
namespace __asan {
+void MaybeReexec() {
+ // No need to re-exec on Linux.
+}
+
void *AsanDoesNotSupportStaticLinkage() {
// This will fail to link with -static.
return &_DYNAMIC; // defined in link.h
}
void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
-#ifdef ANDROID
+#if ASAN_ANDROID
*pc = *sp = *bp = 0;
#elif defined(__arm__)
ucontext_t *ucontext = (ucontext_t*)context;
@@ -63,6 +67,27 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
*pc = ucontext->uc_mcontext.gregs[REG_EIP];
*bp = ucontext->uc_mcontext.gregs[REG_EBP];
*sp = ucontext->uc_mcontext.gregs[REG_ESP];
+# elif defined(__powerpc__) || defined(__powerpc64__)
+ ucontext_t *ucontext = (ucontext_t*)context;
+ *pc = ucontext->uc_mcontext.regs->nip;
+ *sp = ucontext->uc_mcontext.regs->gpr[PT_R1];
+ // The powerpc{,64}-linux ABIs do not specify r31 as the frame
+ // pointer, but GCC always uses r31 when we need a frame pointer.
+ *bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
+# elif defined(__sparc__)
+ ucontext_t *ucontext = (ucontext_t*)context;
+ uptr *stk_ptr;
+# if defined (__arch64__)
+ *pc = ucontext->uc_mcontext.mc_gregs[MC_PC];
+ *sp = ucontext->uc_mcontext.mc_gregs[MC_O6];
+ stk_ptr = (uptr *) (*sp + 2047);
+ *bp = stk_ptr[15];
+# else
+ *pc = ucontext->uc_mcontext.gregs[REG_PC];
+ *sp = ucontext->uc_mcontext.gregs[REG_O6];
+ stk_ptr = (uptr *) *sp;
+ *bp = stk_ptr[15];
+# endif
#else
# error "Unsupported arch"
#endif
@@ -76,69 +101,35 @@ void AsanPlatformThreadInit() {
// Nothing here for now.
}
-AsanLock::AsanLock(LinkerInitialized) {
- // We assume that pthread_mutex_t initialized to all zeroes is a valid
- // unlocked mutex. We can not use PTHREAD_MUTEX_INITIALIZER as it triggers
- // a gcc warning:
- // extended initializer lists only available with -std=c++0x or -std=gnu++0x
-}
-
-void AsanLock::Lock() {
- CHECK(sizeof(pthread_mutex_t) <= sizeof(opaque_storage_));
- pthread_mutex_lock((pthread_mutex_t*)&opaque_storage_);
- CHECK(!owner_);
- owner_ = (uptr)pthread_self();
-}
-
-void AsanLock::Unlock() {
- CHECK(owner_ == (uptr)pthread_self());
- owner_ = 0;
- pthread_mutex_unlock((pthread_mutex_t*)&opaque_storage_);
-}
-
-#ifdef __arm__
-#define UNWIND_STOP _URC_END_OF_STACK
-#define UNWIND_CONTINUE _URC_NO_REASON
-#else
-#define UNWIND_STOP _URC_NORMAL_STOP
-#define UNWIND_CONTINUE _URC_NO_REASON
-#endif
-
-uptr Unwind_GetIP(struct _Unwind_Context *ctx) {
-#ifdef __arm__
- uptr val;
- _Unwind_VRS_Result res = _Unwind_VRS_Get(ctx, _UVRSC_CORE,
- 15 /* r15 = PC */, _UVRSD_UINT32, &val);
- CHECK(res == _UVRSR_OK && "_Unwind_VRS_Get failed");
- // Clear the Thumb bit.
- return val & ~(uptr)1;
-#else
- return _Unwind_GetIP(ctx);
+void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) {
+#if defined(__arm__) || \
+ defined(__powerpc__) || defined(__powerpc64__) || \
+ defined(__sparc__)
+ fast = false;
#endif
+ if (!fast)
+ return stack->SlowUnwindStack(pc, max_s);
+ stack->size = 0;
+ stack->trace[0] = pc;
+ if (max_s > 1) {
+ stack->max_size = max_s;
+ if (!asan_inited) return;
+ if (AsanThread *t = asanThreadRegistry().GetCurrent())
+ stack->FastUnwindStack(pc, bp, t->stack_top(), t->stack_bottom());
+ }
}
-_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx,
- void *param) {
- AsanStackTrace *b = (AsanStackTrace*)param;
- CHECK(b->size < b->max_size);
- uptr pc = Unwind_GetIP(ctx);
- b->trace[b->size++] = pc;
- if (b->size == b->max_size) return UNWIND_STOP;
- return UNWIND_CONTINUE;
+#if !ASAN_ANDROID
+void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
+ ucontext_t *ucp = (ucontext_t*)context;
+ *stack = (uptr)ucp->uc_stack.ss_sp;
+ *ssize = ucp->uc_stack.ss_size;
}
-
-void AsanStackTrace::GetStackTrace(uptr max_s, uptr pc, uptr bp) {
- size = 0;
- trace[0] = pc;
- if ((max_s) > 1) {
- max_size = max_s;
-#ifdef __arm__
- _Unwind_Backtrace(Unwind_Trace, this);
#else
- FastUnwindStack(pc, bp);
-#endif
- }
+void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
+ UNIMPLEMENTED();
}
+#endif
} // namespace __asan