// Copyright 2021 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.

#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_
#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_RISCV_INL_H_

// Generate stack trace for riscv

#include <sys/ucontext.h>

#include "absl/base/config.h"
#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/stacktrace.h"

static const uintptr_t kUnknownFrameSize = 0;

// 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,
                              const std::pair<size_t, size_t> range) {
  //               .
  //               .
  //               .
  //   +-> +----------------+
  //   |   | return address |
  //   |   |   previous fp  |
  //   |   |      ...       |
  //   |   +----------------+ <-+
  //   |   | return address |   |
  //   +---|-  previous fp  |   |
  //       |      ...       |   |
  // $fp ->|----------------+   |
  //       | return address |   |
  //       |   previous fp -|---+
  // $sp ->|      ...       |
  //       +----------------+
  void **new_frame_pointer = reinterpret_cast<void **>(old_frame_pointer[-2]);
  uintptr_t frame_pointer = reinterpret_cast<uintptr_t>(new_frame_pointer);

  // The RISCV ELF psABI mandates that the stack pointer is always 16-byte
  // aligned.
  // TODO(#1236) this doesn't hold for ILP32E which only mandates a 4-byte
  // alignment.
  if (frame_pointer & 15)
    return nullptr;

  // If the new frame pointer matches the signal context, avoid terminating
  // early to deal with alternate signal stacks.
  if (WITH_CONTEXT)
    if (const ucontext_t *ucv = static_cast<const ucontext_t *>(uc))
      // RISCV ELF psABI has the frame pointer at x8/fp/s0.
      // -- RISCV psABI Table 18.2
      if (ucv->uc_mcontext.__gregs[8] == frame_pointer)
        return new_frame_pointer;

  // 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.
  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) {
    if (STRICT_UNWINDING)
      return nullptr;

    // In non-strict mode permit non-contiguous stacks (e.g. alternate signal
    // frame handling).
    if (reinterpret_cast<uintptr_t>(new_frame_pointer) < range.first ||
        reinterpret_cast<uintptr_t>(new_frame_pointer) > range.second)
      return nullptr;
  }

  if (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) {
  // The `frame_pointer` that is computed here points to the top of the frame.
  // The two words preceding the address are the return address and the previous
  // frame pointer.
#if defined(__GNUC__)
  void **frame_pointer = reinterpret_cast<void **>(__builtin_frame_address(0));
#else
#error reading stack pointer not yet supported on this platform
#endif

  std::pair<size_t, size_t> stack = {
      // assume that the first page is not the stack.
      static_cast<size_t>(sysconf(_SC_PAGESIZE)),
      std::numeric_limits<size_t>::max() - sizeof(void *)
  };

  int n = 0;
  void *return_address = nullptr;
  while (frame_pointer && n < max_depth) {
    return_address = frame_pointer[-1];

    // 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,
                                                          stack);

    if (skip_count > 0) {
      skip_count--;
    } else {
      result[n] = return_address;
      if (IS_STACK_FRAMES) {
        sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer);
      }
      n++;
    }

    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 num_dropped_frames = 0;
    for (int j = 0; frame_pointer != nullptr && j < kMaxUnwind; j++) {
      if (skip_count > 0) {
        skip_count--;
      } else {
        num_dropped_frames++;
      }
      frame_pointer =
          NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(frame_pointer, ucp,
                                                            stack);
    }
    *min_dropped_frames = num_dropped_frames;
  }

  return n;
}

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

#endif
