diff options
author | Andrew Turner <andrew@FreeBSD.org> | 2013-01-18 20:06:45 +0000 |
---|---|---|
committer | Andrew Turner <andrew@FreeBSD.org> | 2013-01-18 20:06:45 +0000 |
commit | 58aabf08b77d221489f10e274812ec60917c21a8 (patch) | |
tree | b946f82269be87d83f086167c762c362e734c5bb /lib/asan/asan_linux.cc | |
parent | 37dfff057418e02f8e5322da12684dd927e3d881 (diff) | |
download | src-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.cc | 111 |
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 |