// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#ifndef ZIRCON_KERNEL_PHYS_INCLUDE_PHYS_FRAME_POINTER_H_
#define ZIRCON_KERNEL_PHYS_INCLUDE_PHYS_FRAME_POINTER_H_

#include <cstdint>

class FramePointer {
 public:
  FramePointer() = default;
  FramePointer(const FramePointer&) = default;
  FramePointer& operator=(const FramePointer&) = default;

  // A FramePointer is a forward iterator that also acts as its own container.
  // So in a range-based for loop it yields a list of uintptr_t PC values.
  using iterator = FramePointer;
  using const_iterator = iterator;
  using value_type = uintptr_t;

  // Container interface.

  bool empty() const { return begin() == end(); }

  iterator begin() const { return *this; }

  iterator end() const { return {}; }

  // Iterator interface.

  bool operator==(const FramePointer& fp) const { return fp.fp_ == fp_ && fp.pc_ == pc_; }
  bool operator!=(const FramePointer& fp) const { return !(*this == fp); }

  FramePointer& operator++();  // prefix

  FramePointer operator++(int) {  // postfix
    auto old = *this;
    ++*this;
    return old;
  }

  auto operator*() const { return pc_; }

  // The caller evaluates the default argument to supply its own backtrace:
  // `for (uintptr_t pc : FramePointer::BackTrace()) { ... }` or
  // `vector<uintptr_t>(FramePointer::BackTrace(), FramePointer::end())`.
  // That way the immediate caller itself is not included in the backtrace.
  static const FramePointer& BackTrace(
      const FramePointer* fp = reinterpret_cast<FramePointer*>(__builtin_frame_address(0))) {
    return *fp;
  }

 private:
  // This FP points to its caller's FP and PC.  A call pushes the PC and the
  // prologue then pushes the caller's FP (x86), or the prologue pushes the LR
  // and PC together (ARM); and then sets the FP to the SP.  Since the stack
  // grows down, the PC is always just after the FP in memory.
  const FramePointer* fp_ = nullptr;
  value_type pc_ = 0;
};

#endif  // ZIRCON_KERNEL_PHYS_INCLUDE_PHYS_FRAME_POINTER_H_
