1 //===------------------ sanitizer_unwind_fuchsia.cpp
2 //---------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 /// Sanitizer unwind Fuchsia specific functions.
12 //===----------------------------------------------------------------------===//
14 #include "sanitizer_platform.h"
20 # include "sanitizer_common.h"
21 # include "sanitizer_stacktrace.h"
23 namespace __sanitizer
{
25 # if SANITIZER_CAN_SLOW_UNWIND
26 struct UnwindTraceArg
{
27 BufferedStackTrace
*stack
;
31 _Unwind_Reason_Code
Unwind_Trace(struct _Unwind_Context
*ctx
, void *param
) {
32 UnwindTraceArg
*arg
= static_cast<UnwindTraceArg
*>(param
);
33 CHECK_LT(arg
->stack
->size
, arg
->max_depth
);
34 uptr pc
= _Unwind_GetIP(ctx
);
35 if (pc
< GetPageSizeCached())
36 return _URC_NORMAL_STOP
;
37 arg
->stack
->trace_buffer
[arg
->stack
->size
++] = pc
;
38 return (arg
->stack
->size
== arg
->max_depth
? _URC_NORMAL_STOP
42 void BufferedStackTrace::UnwindSlow(uptr pc
, u32 max_depth
) {
43 CHECK_GE(max_depth
, 2);
45 UnwindTraceArg arg
= {this, Min(max_depth
+ 1, kStackTraceMax
)};
46 _Unwind_Backtrace(Unwind_Trace
, &arg
);
48 // We need to pop a few frames so that pc is on top.
49 uptr to_pop
= LocatePcInTrace(pc
);
50 // trace_buffer[0] belongs to the current function so we always pop it,
51 // unless there is only 1 frame in the stack trace (1 frame is always better
53 PopStackFrames(Min(to_pop
, static_cast<uptr
>(1)));
57 void BufferedStackTrace::UnwindSlow(uptr pc
, void *context
, u32 max_depth
) {
59 CHECK_GE(max_depth
, 2);
60 UNREACHABLE("signal context doesn't exist");
62 # endif // SANITIZER_CAN_SLOW_UNWIND
64 } // namespace __sanitizer
66 #endif // SANITIZER_FUCHSIA