summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r--compiler-rt/lib/asan/asan_interceptors.cc2
-rw-r--r--compiler-rt/lib/asan/asan_linux.cc45
-rw-r--r--compiler-rt/lib/asan/asan_mac.cc25
-rw-r--r--compiler-rt/lib/asan/asan_posix.cc2
-rw-r--r--compiler-rt/lib/asan/asan_rtl.cc7
-rw-r--r--compiler-rt/lib/asan/asan_stack.cc8
-rw-r--r--compiler-rt/lib/asan/asan_stack.h38
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(); \
} \
OpenPOWER on IntegriCloud