diff options
Diffstat (limited to 'compiler-rt')
| -rw-r--r-- | compiler-rt/lib/asan/asan_interceptors.cc | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_linux.cc | 45 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_mac.cc | 25 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_posix.cc | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_rtl.cc | 7 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_stack.cc | 8 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_stack.h | 38 |
7 files changed, 79 insertions, 48 deletions
diff --git a/compiler-rt/lib/asan/asan_interceptors.cc b/compiler-rt/lib/asan/asan_interceptors.cc index 088784ef0fc..e32d113811a 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cc +++ b/compiler-rt/lib/asan/asan_interceptors.cc @@ -278,7 +278,7 @@ __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); + GET_STACK_TRACE_HERE(kStackTraceMax); int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); asanThreadRegistry().RegisterThread(t); diff --git a/compiler-rt/lib/asan/asan_linux.cc b/compiler-rt/lib/asan/asan_linux.cc index ae45b8287ca..7547b8b9aa3 100644 --- a/compiler-rt/lib/asan/asan_linux.cc +++ b/compiler-rt/lib/asan/asan_linux.cc @@ -29,6 +29,7 @@ #include <pthread.h> #include <stdio.h> #include <unistd.h> +#include <unwind.h> #ifndef ANDROID // FIXME: where to get ucontext on Android? @@ -338,6 +339,50 @@ void AsanLock::Unlock() { 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 + +uintptr_t Unwind_GetIP(struct _Unwind_Context *ctx) { +#ifdef __arm__ + uintptr_t 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 & ~(uintptr_t)1; +#else + return _Unwind_GetIP(ctx); +#endif +} + +_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, + void *param) { + AsanStackTrace *b = (AsanStackTrace*)param; + CHECK(b->size < b->max_size); + uintptr_t pc = Unwind_GetIP(ctx); + b->trace[b->size++] = pc; + if (b->size == b->max_size) return UNWIND_STOP; + return UNWIND_CONTINUE; +} + +void AsanStackTrace::GetStackTrace(size_t max_s, uintptr_t pc, uintptr_t 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 + } +} + } // namespace __asan #endif // __linux__ diff --git a/compiler-rt/lib/asan/asan_mac.cc b/compiler-rt/lib/asan/asan_mac.cc index 80463dd663e..f6ec8901e1c 100644 --- a/compiler-rt/lib/asan/asan_mac.cc +++ b/compiler-rt/lib/asan/asan_mac.cc @@ -263,6 +263,15 @@ void AsanLock::Unlock() { OSSpinLockUnlock((OSSpinLock*)&opaque_storage_); } +void AsanStackTrace::GetStackTrace(size_t max_s, uintptr_t pc, uintptr_t bp) { + size = 0; + trace[0] = pc; + if ((max_s) > 1) { + max_size = max_s; + FastUnwindStack(pc, bp); + } +} + // The range of pages to be used by __asan_mach_override_ptr for escape // islands. // TODO(glider): instead of mapping a fixed range we must find a range of @@ -335,7 +344,7 @@ mach_error_t __asan_deallocate_island(void *ptr) { extern "C" void asan_dispatch_call_block_and_release(void *block) { - GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); + GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *context = (asan_block_context_t*)block; if (FLAG_v >= 2) { Report("asan_dispatch_call_block_and_release(): " @@ -376,7 +385,7 @@ extern "C" int WRAP(dispatch_async_f)(dispatch_queue_t dq, void *ctxt, dispatch_function_t func) { - GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); + GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { Report("dispatch_async_f(): context: %p, pthread_self: %p\n", @@ -391,7 +400,7 @@ extern "C" int WRAP(dispatch_sync_f)(dispatch_queue_t dq, void *ctxt, dispatch_function_t func) { - GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); + GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { Report("dispatch_sync_f(): context: %p, pthread_self: %p\n", @@ -407,7 +416,7 @@ int WRAP(dispatch_after_f)(dispatch_time_t when, dispatch_queue_t dq, void *ctxt, dispatch_function_t func) { - GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); + GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { Report("dispatch_after_f: %p\n", asan_ctxt); @@ -420,7 +429,7 @@ int WRAP(dispatch_after_f)(dispatch_time_t when, extern "C" void WRAP(dispatch_barrier_async_f)(dispatch_queue_t dq, void *ctxt, dispatch_function_t func) { - GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); + GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { Report("dispatch_barrier_async_f(): context: %p, pthread_self: %p\n", @@ -435,7 +444,7 @@ extern "C" void WRAP(dispatch_group_async_f)(dispatch_group_t group, dispatch_queue_t dq, void *ctxt, dispatch_function_t func) { - GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); + GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { Report("dispatch_group_async_f(): context: %p, pthread_self: %p\n", @@ -460,7 +469,7 @@ void *wrap_workitem_func(void *arg) { asan_block_context_t *ctxt = (asan_block_context_t*)arg; worker_t fn = (worker_t)(ctxt->func); void *result = fn(ctxt->block); - GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); + GET_STACK_TRACE_HERE(kStackTraceMax); asan_free(arg, &stack); return result; } @@ -469,7 +478,7 @@ extern "C" int WRAP(pthread_workqueue_additem_np)(pthread_workqueue_t workq, void *(*workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp) { - GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); + GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = (asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), &stack); asan_ctxt->block = workitem_arg; diff --git a/compiler-rt/lib/asan/asan_posix.cc b/compiler-rt/lib/asan/asan_posix.cc index b7e21bd84a7..cac35899bc8 100644 --- a/compiler-rt/lib/asan/asan_posix.cc +++ b/compiler-rt/lib/asan/asan_posix.cc @@ -52,7 +52,7 @@ static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) { addr, pc, sp, bp, asanThreadRegistry().GetCurrentTidOrMinusOne()); Printf("AddressSanitizer can not provide additional info. ABORTING\n"); - GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, false, pc, bp); + GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp); stack.PrintStack(); ShowStatsAndAbort(); } diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc index 7a9b0d401e0..774cb25a42c 100644 --- a/compiler-rt/lib/asan/asan_rtl.cc +++ b/compiler-rt/lib/asan/asan_rtl.cc @@ -28,7 +28,6 @@ namespace __asan { // -------------------------- Flags ------------------------- {{{1 static const size_t kMallocContextSize = 30; static int FLAG_atexit; -bool FLAG_fast_unwind = true; size_t FLAG_redzone; // power of two, >= 32 size_t FLAG_quarantine_size; @@ -341,9 +340,7 @@ void __asan_report_error(uintptr_t pc, uintptr_t bp, uintptr_t sp, PrintBytes("PC: ", (uintptr_t*)pc); } - GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, - false, // FLAG_fast_unwind, - pc, bp); + GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp); stack.PrintStack(); CHECK(AddrIsInMem(addr)); @@ -400,7 +397,6 @@ void __asan_init() { FLAG_demangle = IntFlagValue(options, "demangle=", 1); FLAG_debug = IntFlagValue(options, "debug=", 0); FLAG_replace_cfallocator = IntFlagValue(options, "replace_cfallocator=", 1); - FLAG_fast_unwind = IntFlagValue(options, "fast_unwind=", 1); FLAG_replace_str = IntFlagValue(options, "replace_str=", 1); FLAG_replace_intrin = IntFlagValue(options, "replace_intrin=", 1); FLAG_use_fake_stack = IntFlagValue(options, "use_fake_stack=", 1); @@ -437,7 +433,6 @@ void __asan_init() { MEM_TO_SHADOW(kHighShadowEnd)); Printf("red_zone=%ld\n", FLAG_redzone); Printf("malloc_context_size=%ld\n", (int)FLAG_malloc_context_size); - Printf("fast_unwind=%d\n", (int)FLAG_fast_unwind); Printf("SHADOW_SCALE: %lx\n", SHADOW_SCALE); Printf("SHADOW_GRANULARITY: %lx\n", SHADOW_GRANULARITY); diff --git a/compiler-rt/lib/asan/asan_stack.cc b/compiler-rt/lib/asan/asan_stack.cc index 60e4f92282e..9f746974908 100644 --- a/compiler-rt/lib/asan/asan_stack.cc +++ b/compiler-rt/lib/asan/asan_stack.cc @@ -54,14 +54,6 @@ void AsanStackTrace::PrintStack(uintptr_t *addr, size_t size) { } #endif // ASAN_USE_EXTERNAL_SYMBOLIZER -#ifdef __arm__ -#define UNWIND_STOP _URC_END_OF_STACK -#define UNWIND_CONTINUE _URC_OK -#else -#define UNWIND_STOP _URC_NORMAL_STOP -#define UNWIND_CONTINUE _URC_NO_REASON -#endif - uintptr_t AsanStackTrace::GetCurrentPc() { return GET_CALLER_PC(); } diff --git a/compiler-rt/lib/asan/asan_stack.h b/compiler-rt/lib/asan/asan_stack.h index 4b54e084f82..1327d2c789b 100644 --- a/compiler-rt/lib/asan/asan_stack.h +++ b/compiler-rt/lib/asan/asan_stack.h @@ -43,16 +43,16 @@ struct AsanStackTrace { } } + void GetStackTrace(size_t max_s, uintptr_t pc, uintptr_t bp); + void FastUnwindStack(uintptr_t pc, uintptr_t bp); -// static _Unwind_Reason_Code Unwind_Trace( -// struct _Unwind_Context *ctx, void *param); + static uintptr_t GetCurrentPc(); static size_t CompressStack(AsanStackTrace *stack, uint32_t *compressed, size_t size); static void UncompressStack(AsanStackTrace *stack, uint32_t *compressed, size_t size); - size_t full_frame_count; }; } // namespace __asan @@ -61,37 +61,27 @@ struct AsanStackTrace { // The pc will be in the position 0 of the resulting stack trace. // The bp may refer to the current frame or to the caller's frame. // fast_unwind is currently unused. -#define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, fast_unwind, pc, bp) \ - AsanStackTrace stack; \ - { \ - uintptr_t saved_pc = pc; \ - uintptr_t saved_bp = bp; \ - stack.size = 0; \ - stack.full_frame_count = 0; \ - stack.trace[0] = saved_pc; \ - if ((max_s) > 1) { \ - stack.max_size = max_s; \ - stack.FastUnwindStack(saved_pc, saved_bp); \ - } \ - } \ +#define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp) \ + AsanStackTrace stack; \ + stack.GetStackTrace(max_s, pc, bp); \ // NOTE: A Rule of thumb is to retrieve stack trace in the interceptors // as early as possible (in functions exposed to the user), as we generally // don't want stack trace to contain functions from ASan internals. -#define GET_STACK_TRACE_HERE(max_size, fast_unwind) \ - GET_STACK_TRACE_WITH_PC_AND_BP(max_size, fast_unwind, \ - AsanStackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) \ +#define GET_STACK_TRACE_HERE(max_size) \ + GET_STACK_TRACE_WITH_PC_AND_BP(max_size, \ + AsanStackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) \ -#define GET_STACK_TRACE_HERE_FOR_MALLOC \ - GET_STACK_TRACE_HERE(FLAG_malloc_context_size, FLAG_fast_unwind) +#define GET_STACK_TRACE_HERE_FOR_MALLOC \ + GET_STACK_TRACE_HERE(FLAG_malloc_context_size) -#define GET_STACK_TRACE_HERE_FOR_FREE(ptr) \ - GET_STACK_TRACE_HERE(FLAG_malloc_context_size, FLAG_fast_unwind) +#define GET_STACK_TRACE_HERE_FOR_FREE(ptr) \ + GET_STACK_TRACE_HERE(FLAG_malloc_context_size) #define PRINT_CURRENT_STACK() \ { \ - GET_STACK_TRACE_HERE(kStackTraceMax, false); \ + GET_STACK_TRACE_HERE(kStackTraceMax); \ stack.PrintStack(); \ } \ |

