/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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
 *
 *      http://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 _LIBUNWINDSTACK_REGS_H
#define _LIBUNWINDSTACK_REGS_H

#include <stdint.h>

#ifdef __Fuchsia__
// TODO(brettw) upstream this addition. It's technically required by this
// header for its use of pid_t.
#include <unistd.h>
#endif  // __Fuchsia__

#include <functional>
#include <string>
#include <vector>

namespace unwindstack {

// Forward declarations.
class Elf;
enum ArchEnum : uint8_t;
class Memory;

class Regs {
 public:
  enum LocationEnum : uint8_t {
    LOCATION_UNKNOWN = 0,
    LOCATION_REGISTER,
    LOCATION_SP_OFFSET,
  };

  struct Location {
    Location(LocationEnum type, int16_t value) : type(type), value(value) {}

    LocationEnum type;
    int16_t value;
  };

  Regs(uint16_t total_regs, const Location& return_loc)
      : total_regs_(total_regs), return_loc_(return_loc) {}
  virtual ~Regs() = default;

  virtual ArchEnum Arch() = 0;

  virtual bool Is32Bit() = 0;

  virtual void* RawData() = 0;
  virtual uint64_t pc() = 0;
  virtual uint64_t sp() = 0;

  virtual void set_pc(uint64_t pc) = 0;
  virtual void set_sp(uint64_t sp) = 0;

  uint64_t dex_pc() { return dex_pc_; }
  void set_dex_pc(uint64_t dex_pc) { dex_pc_ = dex_pc; }

  virtual uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) = 0;

  virtual bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) = 0;

  virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0;

  virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) = 0;

  uint16_t total_regs() { return total_regs_; }

  virtual Regs* Clone() = 0;

  static ArchEnum CurrentArch();
  static Regs* RemoteGet(pid_t pid);
  static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext);
  static Regs* CreateFromLocal();

 protected:
  uint16_t total_regs_;
  Location return_loc_;
  uint64_t dex_pc_ = 0;
};

template <typename AddressType>
class RegsImpl : public Regs {
 public:
  RegsImpl(uint16_t total_regs, Location return_loc)
      : Regs(total_regs, return_loc), regs_(total_regs), regs_undefined_(total_regs) {}
  virtual ~RegsImpl() = default;

  bool Is32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); }

  inline AddressType& operator[](size_t reg) { return regs_[reg]; }

  inline void SetDefined(size_t reg, bool value) { regs_undefined_[reg] = !value; }

  inline bool IsDefined(size_t reg) { return !regs_undefined_[reg]; }

  void* RawData() override { return regs_.data(); }

  virtual void IterateRegisters(std::function<void(const char*, uint64_t)> fn) override {
    for (size_t i = 0; i < regs_.size(); ++i) {
      if (regs_undefined_[i]) {
        continue;
      }

      fn(std::to_string(i).c_str(), regs_[i]);
    }
  }

 protected:
  std::vector<AddressType> regs_;

  // We store true if a register is undefined rather than defined, even though
  // the interface exposes a bool for whether the register is defined rather
  // than undefined, because we want to take advantage of the default
  // initializer to set all registers to defined by default.
  std::vector<bool> regs_undefined_;
};

}  // namespace unwindstack

#endif  // _LIBUNWINDSTACK_REGS_H
