Home | History | Annotate | Line # | Download | only in sanitizer_common
      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 
     23 namespace __sanitizer {
     24 
     25 void 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