123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- //===------------------ 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
|