sanitizer_unwind_fuchsia.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //===------------------ sanitizer_unwind_fuchsia.cpp
  2. //---------------------------===//
  3. //
  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
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. /// Sanitizer unwind Fuchsia specific functions.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "sanitizer_platform.h"
  14. #if SANITIZER_FUCHSIA
  15. # include <limits.h>
  16. # include <unwind.h>
  17. # include "sanitizer_common.h"
  18. # include "sanitizer_stacktrace.h"
  19. namespace __sanitizer {
  20. # if SANITIZER_CAN_SLOW_UNWIND
  21. struct UnwindTraceArg {
  22. BufferedStackTrace *stack;
  23. u32 max_depth;
  24. };
  25. _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
  26. UnwindTraceArg *arg = static_cast<UnwindTraceArg *>(param);
  27. CHECK_LT(arg->stack->size, arg->max_depth);
  28. uptr pc = _Unwind_GetIP(ctx);
  29. if (pc < GetPageSizeCached())
  30. return _URC_NORMAL_STOP;
  31. arg->stack->trace_buffer[arg->stack->size++] = pc;
  32. return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP
  33. : _URC_NO_REASON);
  34. }
  35. void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
  36. CHECK_GE(max_depth, 2);
  37. size = 0;
  38. UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};
  39. _Unwind_Backtrace(Unwind_Trace, &arg);
  40. CHECK_GT(size, 0);
  41. // We need to pop a few frames so that pc is on top.
  42. uptr to_pop = LocatePcInTrace(pc);
  43. // trace_buffer[0] belongs to the current function so we always pop it,
  44. // unless there is only 1 frame in the stack trace (1 frame is always better
  45. // than 0!).
  46. PopStackFrames(Min(to_pop, static_cast<uptr>(1)));
  47. trace_buffer[0] = pc;
  48. }
  49. void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
  50. CHECK(context);
  51. CHECK_GE(max_depth, 2);
  52. UNREACHABLE("signal context doesn't exist");
  53. }
  54. # endif // SANITIZER_CAN_SLOW_UNWIND
  55. } // namespace __sanitizer
  56. #endif // SANITIZER_FUCHSIA