diff options
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_fuchsia.cpp')
-rw-r--r-- | contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_fuchsia.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_fuchsia.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_fuchsia.cpp new file mode 100644 index 000000000000..f3eb8591dcbc --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_fuchsia.cpp @@ -0,0 +1,66 @@ +//===------------------ sanitizer_unwind_fuchsia.cpp +//---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// Sanitizer unwind Fuchsia specific functions. +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_FUCHSIA + +# include <limits.h> +# include <unwind.h> + +# include "sanitizer_common.h" +# include "sanitizer_stacktrace.h" + +namespace __sanitizer { + +# if SANITIZER_CAN_SLOW_UNWIND +struct UnwindTraceArg { + BufferedStackTrace *stack; + u32 max_depth; +}; + +_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) { + UnwindTraceArg *arg = static_cast<UnwindTraceArg *>(param); + CHECK_LT(arg->stack->size, arg->max_depth); + uptr pc = _Unwind_GetIP(ctx); + if (pc < GetPageSizeCached()) + return _URC_NORMAL_STOP; + arg->stack->trace_buffer[arg->stack->size++] = pc; + return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP + : _URC_NO_REASON); +} + +void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) { + CHECK_GE(max_depth, 2); + size = 0; + UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)}; + _Unwind_Backtrace(Unwind_Trace, &arg); + CHECK_GT(size, 0); + // We need to pop a few frames so that pc is on top. + uptr to_pop = LocatePcInTrace(pc); + // trace_buffer[0] belongs to the current function so we always pop it, + // unless there is only 1 frame in the stack trace (1 frame is always better + // than 0!). + PopStackFrames(Min(to_pop, static_cast<uptr>(1))); + trace_buffer[0] = pc; +} + +void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) { + CHECK(context); + CHECK_GE(max_depth, 2); + UNREACHABLE("signal context doesn't exist"); +} +# endif // SANITIZER_CAN_SLOW_UNWIND + +} // namespace __sanitizer + +#endif // SANITIZER_FUCHSIA |