// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Produce stack trace.
//
// There are three different ways we can try to get the stack trace:
//
// 1) Our hand-coded stack-unwinder.  This depends on a certain stack
//    layout, which is used by gcc (and those systems using a
//    gcc-compatible ABI) on x86 systems, at least since gcc 2.95.
//    It uses the frame pointer to do its work.
//
// 2) The libunwind library.  This is still in development, and as a
//    separate library adds a new dependency, but doesn't need a frame
//    pointer.  It also doesn't call malloc.
//
// 3) The gdb unwinder -- also the one used by the c++ exception code.
//    It's obviously well-tested, but has a fatal flaw: it can call
//    malloc() from the unwinder.  This is a problem because we're
//    trying to use the unwinder to instrument malloc().
//
// Note: if you add a new implementation here, make sure it works
// correctly when absl::GetStackTrace() is called with max_depth == 0.
// Some code may do that.

#include "absl/debugging/stacktrace.h"

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>

#include <algorithm>
#include <atomic>

#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
#include "absl/debugging/internal/stacktrace_config.h"

#if defined(ABSL_STACKTRACE_INL_HEADER)
#include ABSL_STACKTRACE_INL_HEADER
#else
#error Cannot calculate stack trace: will need to write for your environment

#include "absl/debugging/internal/stacktrace_aarch64-inl.inc"
#include "absl/debugging/internal/stacktrace_arm-inl.inc"
#include "absl/debugging/internal/stacktrace_emscripten-inl.inc"
#include "absl/debugging/internal/stacktrace_generic-inl.inc"
#include "absl/debugging/internal/stacktrace_powerpc-inl.inc"
#include "absl/debugging/internal/stacktrace_riscv-inl.inc"
#include "absl/debugging/internal/stacktrace_unimplemented-inl.inc"
#include "absl/debugging/internal/stacktrace_win32-inl.inc"
#include "absl/debugging/internal/stacktrace_x86-inl.inc"
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace {


typedef int (*Unwinder)(void**, int*, int, int, const void*, int*);
std::atomic<Unwinder> custom;

template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
ABSL_ATTRIBUTE_ALWAYS_INLINE inline int Unwind(void** result, uintptr_t* frames,
                                               int* sizes, size_t max_depth,
                                               int skip_count, const void* uc,
                                               int* min_dropped_frames,
                                               bool unwind_with_fixup = true) {
  unwind_with_fixup =
      unwind_with_fixup && internal_stacktrace::ShouldFixUpStack();

#ifdef _WIN32
  if (unwind_with_fixup) {
    // TODO(b/434184677): Fixups are flaky and not supported on Windows
    unwind_with_fixup = false;
#ifndef NDEBUG
    abort();
#endif
  }
#endif

  Unwinder g = custom.load(std::memory_order_acquire);
  size_t size;
  // Add 1 to skip count for the unwinder function itself
  ++skip_count;
  if (g != nullptr) {
    size = static_cast<size_t>((*g)(result, sizes, static_cast<int>(max_depth),
                                    skip_count, uc, min_dropped_frames));
    // Frame pointers aren't returned by existing hooks, so clear them.
    if (frames != nullptr) {
      std::fill(frames, frames + size, uintptr_t());
    }
  } else {
    size = static_cast<size_t>(UnwindImpl<IS_STACK_FRAMES, IS_WITH_CONTEXT>(
        result, frames, sizes, static_cast<int>(max_depth), skip_count, uc,
        min_dropped_frames));
  }
  if (unwind_with_fixup) {
    internal_stacktrace::FixUpStack(result, frames, sizes, max_depth, size);
  }

  ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
  return static_cast<int>(size);
}

}  // anonymous namespace

ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int GetStackFrames(
    void** result, int* sizes, int max_depth, int skip_count) {
  return Unwind<true, false>(result, nullptr, sizes,
                             static_cast<size_t>(max_depth), skip_count,
                             nullptr, nullptr);
}

ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int
internal_stacktrace::GetStackTraceNoFixup(void** result, int max_depth,
                                          int skip_count) {
  return Unwind<false, false>(result, nullptr, nullptr,
                              static_cast<size_t>(max_depth), skip_count,
                              nullptr, nullptr, /*unwind_with_fixup=*/false);
}

ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int
GetStackFramesWithContext(void** result, int* sizes, int max_depth,
                          int skip_count, const void* uc,
                          int* min_dropped_frames) {
  return Unwind<true, true>(result, nullptr, sizes,
                            static_cast<size_t>(max_depth), skip_count, uc,
                            min_dropped_frames);
}

ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int GetStackTrace(
    void** result, int max_depth, int skip_count) {
  return Unwind<false, false>(result, nullptr, nullptr,
                              static_cast<size_t>(max_depth), skip_count,
                              nullptr, nullptr);
}

ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int
GetStackTraceWithContext(void** result, int max_depth, int skip_count,
                         const void* uc, int* min_dropped_frames) {
  return Unwind<false, true>(result, nullptr, nullptr,
                             static_cast<size_t>(max_depth), skip_count, uc,
                             min_dropped_frames);
}

void SetStackUnwinder(Unwinder w) {
  custom.store(w, std::memory_order_release);
}

int DefaultStackUnwinder(void** pcs, int* sizes, int depth, int skip,
                         const void* uc, int* min_dropped_frames) {
  skip++;  // For this function
  decltype(&UnwindImpl<false, false>) f;
  if (sizes == nullptr) {
    if (uc == nullptr) {
      f = &UnwindImpl<false, false>;
    } else {
      f = &UnwindImpl<false, true>;
    }
  } else {
    if (uc == nullptr) {
      f = &UnwindImpl<true, false>;
    } else {
      f = &UnwindImpl<true, true>;
    }
  }
  int n = (*f)(pcs, nullptr, sizes, depth, skip, uc, min_dropped_frames);
  ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
  return n;
}

ABSL_ATTRIBUTE_WEAK bool internal_stacktrace::ShouldFixUpStack() {
  return false;
}

// Fixes up the stack trace of the current thread, in the first `depth` frames
// of each buffer. The buffers need to be larger than `depth`, to accommodate
// any newly inserted elements. `depth` is updated to reflect the new number of
// elements valid across all the buffers. (It is therefore recommended that all
// buffer sizes be equal.)
//
// The `frames` and `sizes` parameters denote the bounds of the stack frame
// corresponding to each instruction pointer in the `pcs`.
// Any elements inside these buffers may be zero or null, in which case that
// information is assumed to be absent/unavailable.
ABSL_ATTRIBUTE_WEAK void internal_stacktrace::FixUpStack(void**, uintptr_t*,
                                                         int*, size_t,
                                                         size_t&) {}

ABSL_NAMESPACE_END
}  // namespace absl
