diff options
| author | Walter Lee <waltl@google.com> | 2018-05-10 21:40:16 +0000 |
|---|---|---|
| committer | Walter Lee <waltl@google.com> | 2018-05-10 21:40:16 +0000 |
| commit | 603c7ae232a9a7d379738ce1720cd4db3d97f05a (patch) | |
| tree | eafbe40431ccb30b43c1ee849e3d16d25ff458da /compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cc | |
| parent | e7e1d9349b04a250b9f67eb5efd3dec0d942c9d4 (diff) | |
| download | bcm5719-llvm-603c7ae232a9a7d379738ce1720cd4db3d97f05a.tar.gz bcm5719-llvm-603c7ae232a9a7d379738ce1720cd4db3d97f05a.zip | |
[sanitizer] Port fast stack unwinder to sparcv8
Differential Revision: https://reviews.llvm.org/D46469
llvm-svn: 332046
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cc')
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cc | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cc new file mode 100644 index 00000000000..9f9920ece80 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_sparc.cc @@ -0,0 +1,58 @@ +//===-- sanitizer_stacktrace_sparc.cc -------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between AddressSanitizer and ThreadSanitizer +// run-time libraries. +// +// Implemention of fast stack unwinding for Sparc. +//===----------------------------------------------------------------------===// + +// This file is ported to Sparc v8, but it should be easy to port to +// Sparc v9. +#if defined(__sparcv8__) + +#include "sanitizer_common.h" +#include "sanitizer_stacktrace.h" + +namespace __sanitizer { + +void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, + uptr stack_bottom, u32 max_depth) { + const uptr kPageSize = GetPageSizeCached(); + CHECK_GE(max_depth, 2); + trace_buffer[0] = pc; + size = 1; + if (stack_top < 4096) return; // Sanity check for stack top. + // Flush register windows to memory + asm volatile("ta 3" ::: "memory"); + uhwptr *frame = (uhwptr*)bp; + // Lowest possible address that makes sense as the next frame pointer. + // Goes up as we walk the stack. + uptr bottom = stack_bottom; + // Avoid infinite loop when frame == frame[0] by using frame > prev_frame. + while (IsValidFrame((uptr)frame, stack_top, bottom) && + IsAligned((uptr)frame, sizeof(*frame)) && + size < max_depth) { + uhwptr pc1 = frame[15]; + // Let's assume that any pointer in the 0th page is invalid and + // stop unwinding here. If we're adding support for a platform + // where this isn't true, we need to reconsider this check. + if (pc1 < kPageSize) + break; + if (pc1 != pc) { + trace_buffer[size++] = (uptr) pc1; + } + bottom = (uptr)frame; + frame = (uhwptr*)frame[14]; + } +} + +} // namespace __sanitizer + +#endif // !defined(__sparcv8__) |

