forked from OSchip/llvm-project
[sanitizer] Port fast stack unwinder to sparcv8
Differential Revision: https://reviews.llvm.org/D46469 llvm-svn: 332046
This commit is contained in:
parent
e7e1d9349b
commit
603c7ae232
|
@ -72,6 +72,7 @@ set(SANITIZER_SYMBOLIZER_SOURCES
|
|||
sanitizer_stacktrace.cc
|
||||
sanitizer_stacktrace_libcdep.cc
|
||||
sanitizer_stacktrace_printer.cc
|
||||
sanitizer_stacktrace_sparc.cc
|
||||
sanitizer_symbolizer.cc
|
||||
sanitizer_symbolizer_fuchsia.cc
|
||||
sanitizer_symbolizer_libbacktrace.cc
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace __sanitizer {
|
|||
uptr StackTrace::GetNextInstructionPc(uptr pc) {
|
||||
#if defined(__mips__)
|
||||
return pc + 8;
|
||||
#elif defined(__powerpc__)
|
||||
#elif defined(__powerpc__) || defined(__sparc__)
|
||||
return pc + 4;
|
||||
#else
|
||||
return pc + 1;
|
||||
|
@ -40,6 +40,9 @@ void BufferedStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) {
|
|||
top_frame_bp = 0;
|
||||
}
|
||||
|
||||
// Sparc implemention is in its own file.
|
||||
#if !defined(__sparc__)
|
||||
|
||||
// In GCC on ARM bp points to saved lr, not fp, so we should check the next
|
||||
// cell in stack to be a saved frame pointer. GetCanonicFrame returns the
|
||||
// pointer to saved frame pointer in any case.
|
||||
|
@ -106,6 +109,8 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
|
|||
}
|
||||
}
|
||||
|
||||
#endif // !defined(__sparc__)
|
||||
|
||||
void BufferedStackTrace::PopStackFrames(uptr count) {
|
||||
CHECK_LT(count, size);
|
||||
size -= count;
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
//===-- sanitizer_stacktrace_sparc.cc -------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// 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__)
|
Loading…
Reference in New Issue