#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_AARCH64_INL_H_
#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_AARCH64_INL_H_

// Generate stack tracer for aarch64

#if defined(__linux__)
#include <sys/mman.h>
#include <ucontext.h>
#include <unistd.h>
#endif

#include <atomic>
#include <cassert>
#include <cstdint>
#include <iostream>

#include "absl/base/attributes.h"
#include "absl/debugging/internal/address_is_readable.h"
#include "absl/debugging/internal/vdso_support.h"  // a no-op on non-elf or non-glibc systems
#include "absl/debugging/stacktrace.h"

static const uintptr_t kUnknownFrameSize = 0;

#if defined(__linux__)
// Returns the address of the VDSO __kernel_rt_sigreturn function, if present.
static const unsigned char* GetKernelRtSigreturnAddress() {
  constexpr uintptr_t kImpossibleAddress = 1;
  ABSL_CONST_INIT static std::atomic<uintptr_t> memoized{kImpossibleAddress};
  uintptr_t address = memoized.load(std::memory_order_relaxed);
  if (address != kImpossibleAddress) {
    return reinterpret_cast<const unsigned char*>(address);
  }

  address = reinterpret_cast<uintptr_t>(nullptr);

#ifdef ABSL_HAVE_VDSO_SUPPORT
  absl::debugging_internal::VDSOSupport vdso;
  if (vdso.IsPresent()) {
    absl::debugging_internal::VDSOSupport::SymbolInfo symbol_info;
    if (!vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_2.6.39", STT_FUNC,
                           &symbol_info) ||
        symbol_info.address == nullptr) {
      // Unexpected: VDSO is present, yet the expected symbol is missing
      // or null.
      assert(false && "VDSO is present, but doesn't have expected symbol");
    } else {
      if (reinterpret_cast<uintptr_t>(symbol_info.address) !=
          kImpossibleAddress) {
        address = reinterpret_cast<uintptr_t>(symbol_info.address);
      } else {
        assert(false && "VDSO returned invalid address");
      }
    }
  }
#endif

  memoized.store(address, std::memory_order_relaxed);
  return reinterpret_cast<const unsigned char*>(address);
}
#endif  // __linux__

// Compute the size of a stack frame in [low..high).  We assume that
// low < high.  Return size of kUnknownFrameSize.
template<typename T>
static inline uintptr_t ComputeStackFrameSize(const T* low,
                                              const T* high) {
  const char* low_char_ptr = reinterpret_cast<const char *>(low);
  const char* high_char_ptr = reinterpret_cast<const char *>(high);
  return low < high ? high_char_ptr - low_char_ptr : kUnknownFrameSize;
}

// Given a pointer to a stack frame, locate and return the calling
// stackframe, or return null if no stackframe can be found. Perform sanity
// checks (the strictness of which is controlled by the boolean parameter
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
template<bool STRICT_UNWINDING, bool WITH_CONTEXT>
ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS  // May read random elements from stack.
ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY   // May read random elements from stack.
static void **NextStackFrame(void **old_frame_pointer, const void *uc) {
  void **new_frame_pointer = reinterpret_cast<void**>(*old_frame_pointer);
  bool check_frame_size = true;

#if defined(__linux__)
  if (WITH_CONTEXT && uc != nullptr) {
    // Check to see if next frame's return address is __kernel_rt_sigreturn.
    if (old_frame_pointer[1] == GetKernelRtSigreturnAddress()) {
      const ucontext_t *ucv = static_cast<const ucontext_t *>(uc);
      // old_frame_pointer[0] is not suitable for unwinding, look at
      // ucontext to discover frame pointer before signal.
      void **const pre_signal_frame_pointer =
          reinterpret_cast<void **>(ucv->uc_mcontext.regs[29]);

      // Check that alleged frame pointer is actually readable. This is to
      // prevent "double fault" in case we hit the first fault due to e.g.
      // stack corruption.
      if (!absl::debugging_internal::AddressIsReadable(
              pre_signal_frame_pointer))
        return nullptr;

      // Alleged frame pointer is readable, use it for further unwinding.
      new_frame_pointer = pre_signal_frame_pointer;

      // Skip frame size check if we return from a signal. We may be using a
      // an alternate stack for signals.
      check_frame_size = false;
    }
  }
#endif

  // aarch64 ABI requires stack pointer to be 16-byte-aligned.
  if ((reinterpret_cast<uintptr_t>(new_frame_pointer) & 15) != 0)
    return nullptr;

  // Check frame size.  In strict mode, we assume frames to be under
  // 100,000 bytes.  In non-strict mode, we relax the limit to 1MB.
  if (check_frame_size) {
    const uintptr_t max_size = STRICT_UNWINDING ? 100000 : 1000000;
    const uintptr_t frame_size =
        ComputeStackFrameSize(old_frame_pointer, new_frame_pointer);
    if (frame_size == kUnknownFrameSize || frame_size > max_size)
      return nullptr;
  }

  return new_frame_pointer;
}

template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS  // May read random elements from stack.
ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY   // May read random elements from stack.
static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
                      const void *ucp, int *min_dropped_frames) {
#ifdef __GNUC__
  void **frame_pointer = reinterpret_cast<void**>(__builtin_frame_address(0));
#else
# error reading stack point not yet supported on this platform.
#endif

  skip_count++;    // Skip the frame for this function.
  int n = 0;

  // The frame pointer points to low address of a frame.  The first 64-bit
  // word of a frame points to the next frame up the call chain, which normally
  // is just after the high address of the current frame.  The second word of
  // a frame contains return adress of to the caller.   To find a pc value
  // associated with the current frame, we need to go down a level in the call
  // chain.  So we remember return the address of the last frame seen.  This
  // does not work for the first stack frame, which belongs to UnwindImp() but
  // we skip the frame for UnwindImp() anyway.
  void* prev_return_address = nullptr;

  while (frame_pointer && n < max_depth) {
    // The absl::GetStackFrames routine is called when we are in some
    // informational context (the failure signal handler for example).
    // Use the non-strict unwinding rules to produce a stack trace
    // that is as complete as possible (even if it contains a few bogus
    // entries in some rare cases).
    void **next_frame_pointer =
        NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp);

    if (skip_count > 0) {
      skip_count--;
    } else {
      result[n] = prev_return_address;
      if (IS_STACK_FRAMES) {
        sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer);
      }
      n++;
    }
    prev_return_address = frame_pointer[1];
    frame_pointer = next_frame_pointer;
  }
  if (min_dropped_frames != nullptr) {
    // Implementation detail: we clamp the max of frames we are willing to
    // count, so as not to spend too much time in the loop below.
    const int kMaxUnwind = 200;
    int j = 0;
    for (; frame_pointer != nullptr && j < kMaxUnwind; j++) {
      frame_pointer =
          NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp);
    }
    *min_dropped_frames = j;
  }
  return n;
}

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
bool StackTraceWorksForTest() {
  return true;
}
}  // namespace debugging_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_DEBUGGING_INTERNAL_STACKTRACE_AARCH64_INL_H_
