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