xref: /openbsd-src/gnu/llvm/compiler-rt/lib/asan/asan_stack.cpp (revision d89ec533011f513df1010f142a111086a0785f09)
13cab2bb3Spatrick //===-- asan_stack.cpp ----------------------------------------------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of AddressSanitizer, an address sanity checker.
103cab2bb3Spatrick //
113cab2bb3Spatrick // Code for ASan stack trace.
123cab2bb3Spatrick //===----------------------------------------------------------------------===//
133cab2bb3Spatrick #include "asan_internal.h"
143cab2bb3Spatrick #include "asan_stack.h"
153cab2bb3Spatrick #include "sanitizer_common/sanitizer_atomic.h"
163cab2bb3Spatrick 
173cab2bb3Spatrick namespace __asan {
183cab2bb3Spatrick 
193cab2bb3Spatrick static atomic_uint32_t malloc_context_size;
203cab2bb3Spatrick 
SetMallocContextSize(u32 size)213cab2bb3Spatrick void SetMallocContextSize(u32 size) {
223cab2bb3Spatrick   atomic_store(&malloc_context_size, size, memory_order_release);
233cab2bb3Spatrick }
243cab2bb3Spatrick 
GetMallocContextSize()253cab2bb3Spatrick u32 GetMallocContextSize() {
263cab2bb3Spatrick   return atomic_load(&malloc_context_size, memory_order_acquire);
273cab2bb3Spatrick }
283cab2bb3Spatrick 
293cab2bb3Spatrick namespace {
303cab2bb3Spatrick 
313cab2bb3Spatrick // ScopedUnwinding is a scope for stacktracing member of a context
323cab2bb3Spatrick class ScopedUnwinding {
333cab2bb3Spatrick  public:
ScopedUnwinding(AsanThread * t)343cab2bb3Spatrick   explicit ScopedUnwinding(AsanThread *t) : thread(t) {
353cab2bb3Spatrick     if (thread) {
363cab2bb3Spatrick       can_unwind = !thread->isUnwinding();
373cab2bb3Spatrick       thread->setUnwinding(true);
383cab2bb3Spatrick     }
393cab2bb3Spatrick   }
~ScopedUnwinding()403cab2bb3Spatrick   ~ScopedUnwinding() {
413cab2bb3Spatrick     if (thread)
423cab2bb3Spatrick       thread->setUnwinding(false);
433cab2bb3Spatrick   }
443cab2bb3Spatrick 
CanUnwind() const453cab2bb3Spatrick   bool CanUnwind() const { return can_unwind; }
463cab2bb3Spatrick 
473cab2bb3Spatrick  private:
483cab2bb3Spatrick   AsanThread *thread = nullptr;
493cab2bb3Spatrick   bool can_unwind = true;
503cab2bb3Spatrick };
513cab2bb3Spatrick 
523cab2bb3Spatrick }  // namespace
533cab2bb3Spatrick 
543cab2bb3Spatrick }  // namespace __asan
553cab2bb3Spatrick 
UnwindImpl(uptr pc,uptr bp,void * context,bool request_fast,u32 max_depth)563cab2bb3Spatrick void __sanitizer::BufferedStackTrace::UnwindImpl(
573cab2bb3Spatrick     uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
583cab2bb3Spatrick   using namespace __asan;
593cab2bb3Spatrick   size = 0;
603cab2bb3Spatrick   if (UNLIKELY(!asan_inited))
613cab2bb3Spatrick     return;
623cab2bb3Spatrick   request_fast = StackTrace::WillUseFastUnwind(request_fast);
633cab2bb3Spatrick   AsanThread *t = GetCurrentThread();
643cab2bb3Spatrick   ScopedUnwinding unwind_scope(t);
653cab2bb3Spatrick   if (!unwind_scope.CanUnwind())
663cab2bb3Spatrick     return;
673cab2bb3Spatrick   if (request_fast) {
683cab2bb3Spatrick     if (t) {
693cab2bb3Spatrick       Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
703cab2bb3Spatrick              true);
713cab2bb3Spatrick     }
723cab2bb3Spatrick     return;
733cab2bb3Spatrick   }
743cab2bb3Spatrick   if (SANITIZER_MIPS && t &&
753cab2bb3Spatrick       !IsValidFrame(bp, t->stack_top(), t->stack_bottom()))
763cab2bb3Spatrick     return;
77*d89ec533Spatrick   Unwind(max_depth, pc, bp, context, t ? t->stack_top() : 0,
78*d89ec533Spatrick          t ? t->stack_bottom() : 0, false);
793cab2bb3Spatrick }
803cab2bb3Spatrick 
813cab2bb3Spatrick // ------------------ Interface -------------- {{{1
823cab2bb3Spatrick 
833cab2bb3Spatrick extern "C" {
843cab2bb3Spatrick SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_print_stack_trace()853cab2bb3Spatrick void __sanitizer_print_stack_trace() {
863cab2bb3Spatrick   using namespace __asan;
873cab2bb3Spatrick   PRINT_CURRENT_STACK();
883cab2bb3Spatrick }
893cab2bb3Spatrick }  // extern "C"
90