2018-11-16 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_stacktrace_sparc.cc
blob7e7017bb1b1d9a9afdad52ecd97579516872dd25
1 //===-- sanitizer_stacktrace_sparc.cc -------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is shared between AddressSanitizer and ThreadSanitizer
9 // run-time libraries.
11 // Implemention of fast stack unwinding for Sparc.
12 //===----------------------------------------------------------------------===//
14 // This file is ported to Sparc v8, but it should be easy to port to
15 // Sparc v9.
16 #if defined(__sparcv8__) || defined(__sparcv8) || defined(__sparc_v8__)
18 #include "sanitizer_common.h"
19 #include "sanitizer_stacktrace.h"
21 namespace __sanitizer {
23 void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
24 uptr stack_bottom, u32 max_depth) {
25 const uptr kPageSize = GetPageSizeCached();
26 CHECK_GE(max_depth, 2);
27 trace_buffer[0] = pc;
28 size = 1;
29 if (stack_top < 4096) return; // Sanity check for stack top.
30 // Flush register windows to memory
31 asm volatile("ta 3" ::: "memory");
32 uhwptr *frame = (uhwptr*)bp;
33 // Lowest possible address that makes sense as the next frame pointer.
34 // Goes up as we walk the stack.
35 uptr bottom = stack_bottom;
36 // Avoid infinite loop when frame == frame[0] by using frame > prev_frame.
37 while (IsValidFrame((uptr)frame, stack_top, bottom) &&
38 IsAligned((uptr)frame, sizeof(*frame)) &&
39 size < max_depth) {
40 uhwptr pc1 = frame[15];
41 // Let's assume that any pointer in the 0th page is invalid and
42 // stop unwinding here. If we're adding support for a platform
43 // where this isn't true, we need to reconsider this check.
44 if (pc1 < kPageSize)
45 break;
46 if (pc1 != pc) {
47 trace_buffer[size++] = (uptr) pc1;
49 bottom = (uptr)frame;
50 frame = (uhwptr*)frame[14];
54 } // namespace __sanitizer
56 #endif // !defined(__sparcv8__) && !defined(__sparcv8) &&
57 // !defined(__sparc_v8__)