1 //===-- sanitizer_stacktrace_sparc.cc -------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is shared between AddressSanitizer and ThreadSanitizer
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
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);
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
)) &&
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.
47 trace_buffer
[size
++] = (uptr
) pc1
;
50 frame
= (uhwptr
*)frame
[14];
54 } // namespace __sanitizer
56 #endif // !defined(__sparcv8__) && !defined(__sparcv8) &&
57 // !defined(__sparc_v8__)