summaryrefslogtreecommitdiff
path: root/lib/asan/asan_stack.h
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2011-11-30 01:07:02 +0000
committerKostya Serebryany <kcc@google.com>2011-11-30 01:07:02 +0000
commit1e172b4bdec57329bf904f063a29f99cddf2d85f (patch)
tree615823ee9e1c1dfa52262cbf608c8e63cd07d0f3 /lib/asan/asan_stack.h
parent1626d864159d42d1c5a492c1cb686f629e81f815 (diff)
downloadcompiler-rt-1e172b4bdec57329bf904f063a29f99cddf2d85f.tar.gz
compiler-rt-1e172b4bdec57329bf904f063a29f99cddf2d85f.tar.bz2
compiler-rt-1e172b4bdec57329bf904f063a29f99cddf2d85f.tar.xz
AddressSanitizer run-time library. Not yet integrated with the compiler-rt build system, but can be built using the old makefile. See details in README.txt
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@145463 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/asan/asan_stack.h')
-rw-r--r--lib/asan/asan_stack.h94
1 files changed, 94 insertions, 0 deletions
diff --git a/lib/asan/asan_stack.h b/lib/asan/asan_stack.h
new file mode 100644
index 00000000..97aefd6d
--- /dev/null
+++ b/lib/asan/asan_stack.h
@@ -0,0 +1,94 @@
+//===-- asan_stack.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// ASan-private header for asan_stack.cc.
+//===----------------------------------------------------------------------===//
+#ifndef ASAN_STACK_H
+#define ASAN_STACK_H
+
+#include "asan_internal.h"
+
+namespace __asan {
+
+static const size_t kStackTraceMax = 64;
+
+struct AsanStackTrace {
+ size_t size;
+ size_t max_size;
+ uintptr_t trace[kStackTraceMax];
+ static void PrintStack(uintptr_t *addr, size_t size);
+ void PrintStack() {
+ PrintStack(this->trace, this->size);
+ }
+ void CopyTo(uintptr_t *dst, size_t dst_size) {
+ for (size_t i = 0; i < size && i < dst_size; i++)
+ dst[i] = trace[i];
+ for (size_t i = size; i < dst_size; i++)
+ dst[i] = 0;
+ }
+
+ void CopyFrom(uintptr_t *src, size_t src_size) {
+ size = src_size;
+ if (size > kStackTraceMax) size = kStackTraceMax;
+ for (size_t i = 0; i < size; i++) {
+ trace[i] = src[i];
+ }
+ }
+
+ 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
+
+// Get the stack trace with the given pc and bp.
+// 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_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_FOR_MALLOC \
+ 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, FLAG_fast_unwind)
+
+#define PRINT_CURRENT_STACK() \
+ { \
+ GET_STACK_TRACE_HERE(kStackTraceMax, false); \
+ stack.PrintStack(); \
+ } \
+
+#endif // ASAN_STACK_H