diff options
author | Martin Liska <mliska@suse.cz> | 2018-10-31 12:14:23 +0100 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2018-10-31 11:14:23 +0000 |
commit | eac975312214dccb9d425b3e8d0b93e85c11ddf4 (patch) | |
tree | 431086825b095506e32d4c0b0e479c62254e2b69 /libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc | |
parent | 95fba530b6f68f336090abb5699ae9f24d1e22e6 (diff) | |
download | gcc-eac975312214dccb9d425b3e8d0b93e85c11ddf4.tar.gz |
backport: All source files: Merge from upstream 345033.
Merge from upstream 345033.
2018-10-31 Martin Liska <mliska@suse.cz>
* All source files: Merge from upstream 345033.
From-SVN: r265665
Diffstat (limited to 'libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc')
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc new file mode 100644 index 00000000000..623fba25ed5 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc @@ -0,0 +1,56 @@ +//===-- sanitizer_stacktrace_sparc.cc -------------------------------------===// +// +// 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__) |