// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVELOPER_DEBUG_IPC_RECORDS_H_
#define SRC_DEVELOPER_DEBUG_IPC_RECORDS_H_

#include <stdint.h>

#include <optional>
#include <string>
#include <vector>

#include "src/developer/debug/ipc/register_desc.h"
#include "src/developer/debug/shared/address_range.h"

namespace debug_ipc {

#pragma pack(push, 8)

enum class ExceptionType : uint32_t {
  // No current exception, used as placeholder or to indicate not set.
  kNone = 0,

  // Zircon defines this as a sort of catch-all exception.
  kGeneral,

  // The usual band of execution traps.
  kPageFault,
  kUndefinedInstruction,
  kUnalignedAccess,

  // Indicates the process was killed due to misusing a syscall, e.g. passing a bad handle.
  kPolicyError,

  // Synthetic exeptions used by zircon to communicated with the debugger. The debug agent generally
  // shouldn't pass these on, but we should recognize them at least.
  kThreadStarting,
  kThreadExiting,
  kProcessStarting,

  // Hardware breakpoints are issues by the CPU via debug registers.
  kHardwareBreakpoint,

  // HW exceptions triggered on memory read/write.
  kWatchpoint,

  // Single-step completion issued by the CPU.
  kSingleStep,

  // Software breakpoint. This will be issued when a breakpoint is hit and when the debugged program
  // manually issues a breakpoint instruction.
  kSoftwareBreakpoint,

  // Indicates this exception is not a real CPU exception but was generated internally for the
  // purposes of sending a stop notification. The frontend uses this value when the thread didn't
  // actually do anything, but the should be updated as if it hit an exception.
  kSynthetic,

  // For exception codes the debugger doesn't recognize.
  kUnknown,

  kLast  // Not an actual exception type, for range checking.
};
const char* ExceptionTypeToString(ExceptionType);
bool IsDebug(ExceptionType);

// Exception handling strategy.
enum class ExceptionStrategy : uint32_t {
  // No current exception, used as placeholder or to indicate not set.
  kNone = 0,

  // Indicates that the debugger only gets the first chance to handle the
  // exception, before the thread and process-level handlers.
  kFirstChance,

  // Indicates that the debugger also gets a second first chance to handle
  //  the exception after process-level handler.
  kSecondChance,

  kLast,  // Not an actual exception strategy, for range checking.
};

const char* ExceptionStrategyToString(ExceptionStrategy);

std::optional<ExceptionStrategy> ToExceptionStrategy(uint32_t raw_value);

std::optional<uint32_t> ToRawValue(ExceptionStrategy strategy);

struct ExceptionRecord {
  ExceptionRecord() { memset(&arch, 0, sizeof(Arch)); }

  // Race conditions or other errors can conspire to mean the exception records are not valid. In
  // order to differentiate this case from "0" addresses, this flag indicates validity of the "arch"
  // union.
  bool valid = false;

  union Arch {
    // Exception record for x64.
    struct {
      uint64_t vector;
      uint64_t err_code;
      uint64_t cr2;
    } x64;

    // Exception record for ARM64.
    struct {
      uint32_t esr;
      uint64_t far;
    } arm64;
  } arch;

  ExceptionStrategy strategy = ExceptionStrategy::kNone;
};

// Note: see "ps" source:
// https://fuchsia.googlesource.com/fuchsia/+/HEAD/src/sys/bin/psutils/ps.c
struct ProcessTreeRecord {
  enum class Type : uint32_t { kJob, kProcess };

  Type type = Type::kJob;
  uint64_t koid = 0;
  std::string name;

  std::vector<ProcessTreeRecord> children;
};

// Value representing a particular register.
struct Register {
  Register() = default;
  Register(RegisterID rid, std::vector<uint8_t> d) : id(rid), data(std::move(d)) {}

  // Constructs from a size and a pointed-to data buffer in machine-endianness.
  Register(RegisterID rid, size_t byte_size, const void* bytes) : id(rid) {
    data.resize(byte_size);
    memcpy(&data[0], bytes, byte_size);
  }

  // Constructs a sized value for the current platform.
  Register(RegisterID rid, uint64_t val) : id(rid) {
    data.resize(sizeof(val));
    memcpy(&data[0], &val, sizeof(val));
  }
  Register(RegisterID rid, uint32_t val) : id(rid) {
    data.resize(sizeof(val));
    memcpy(&data[0], &val, sizeof(val));
  }
  Register(RegisterID rid, uint16_t val) : id(rid) {
    data.resize(sizeof(val));
    memcpy(&data[0], &val, sizeof(val));
  }
  Register(RegisterID rid, uint8_t val) : id(rid) {
    data.resize(sizeof(val));
    memcpy(&data[0], &val, sizeof(val));
  }

  // Retrieves the low up-to-128 bits of the register value as a number.
  __int128 GetValue() const;

  // Comparisons (primarily for tests).
  bool operator==(const Register& other) const { return id == other.id && data == other.data; }
  bool operator!=(const Register& other) const { return !operator==(other); }

  RegisterID id = RegisterID::kUnknown;

  // This data is stored in the architecture's native endianness
  // (eg. the result of running memcpy over the data).
  std::vector<uint8_t> data;
};

struct StackFrame {
  StackFrame() = default;
  StackFrame(uint64_t ip, uint64_t sp, uint64_t cfa = 0, std::vector<Register> r = {})
      : ip(ip), sp(sp), cfa(cfa), regs(std::move(r)) {}

  // Comparisons (primarily for tests).
  bool operator==(const StackFrame& other) const {
    return ip == other.ip && sp == other.sp && cfa == other.cfa && regs == other.regs;
  }
  bool operator!=(const StackFrame& other) const { return !operator==(other); }

  // Instruction pointer.
  uint64_t ip = 0;

  // Stack pointer.
  uint64_t sp = 0;

  // Canonical frame address. This is the stack pointer of the previous
  // frame at the time of the call. 0 if unknown.
  uint64_t cfa = 0;

  // Known general registers for this stack frame. See IsGeneralRegister() for
  // which registers are counted as "general".
  //
  // Every frame should contain the register for the IP and SP for the current
  // architecture (duplicating the above two fields).
  std::vector<Register> regs;
};

struct ThreadRecord {
  enum class State : uint32_t {
    kNew = 0,
    kRunning,
    kSuspended,
    kBlocked,
    kDying,
    kDead,
    kCoreDump,

    kLast  // Not an actual thread state, for range checking.
  };
  static const char* StateToString(State);

  enum class BlockedReason : uint32_t {
    kNotBlocked = 0,  // Used when State isn't kBlocked.

    kException,
    kSleeping,
    kFutex,
    kPort,
    kChannel,
    kWaitOne,
    kWaitMany,
    kInterrupt,
    kPager,

    kLast  // Not an actual blocked reason, for range checking.
  };
  static const char* BlockedReasonToString(BlockedReason);

  // Indicates how much of the stack was attempted to be retrieved in this
  // call. This doesn't indicate how many stack frames were actually retrieved.
  // For example, there could be no stack frames because they weren't
  // requested, or there could be no stack frames due to an error.
  enum class StackAmount : uint32_t {
    // A backtrace was not attempted. This will always be the case if the
    // thread is neither suspended nor blocked in an exception.
    kNone = 0,

    // The frames vector contains a minimal stack only (if available) which
    // is defined as the top two frames. This is used when the stack frames
    // have not been specifically requested since retrieving the full stack
    // can be slow. The frames can still be less than 2 if there was an error
    // or if there is only one stack frame.
    kMinimal,

    // The frames are the full stack trace (up to some maximum).
    kFull,

    kLast  // Not an actual state, for range checking.
  };

  uint64_t process_koid = 0;
  uint64_t thread_koid = 0;
  std::string name;
  State state = State::kNew;
  // Only valid when state is kBlocked.
  BlockedReason blocked_reason = BlockedReason::kNotBlocked;
  StackAmount stack_amount = StackAmount::kNone;

  // The frames of the top of the stack when the thread is in suspended or blocked in an exception
  // (if possible). See stack_amnount for how to interpret this.
  //
  // This could still be empty in the "kMinimal" or "kFull" cases if retrieval failed, which can
  // happen in some valid race conditions if the thread was killed out from under the debug agent.
  std::vector<StackFrame> frames;
};

struct ProcessRecord {
  uint64_t process_koid = 0;
  std::string process_name;

  std::vector<ThreadRecord> threads;
};

struct MemoryBlock {
  // Begin address of this memory.
  uint64_t address = 0;

  // When true, indicates this is valid memory, with the data containing the
  // memory. False means that this range is not mapped in the process and the
  // data will be empty.
  bool valid = false;

  // Length of this range. When valid == true, this will be the same as
  // data.size(). When valid == false, this will be whatever the length of
  // the invalid region is, and data will be empty.
  uint32_t size = 0;

  // The actual memory. Filled in only if valid == true.
  std::vector<uint8_t> data;
};

struct ProcessBreakpointSettings {
  // Required to be nonzero.
  uint64_t process_koid = 0;

  // Zero indicates this is a process-wide breakpoint. Otherwise, this is the thread to break.
  uint64_t thread_koid = 0;

  // Address to break at.
  uint64_t address = 0;

  // Range is used for watchpoints.
  AddressRange address_range;
};

// What threads to stop when the breakpoint is hit.
enum class Stop : uint32_t {
  kAll,      // Stop all threads of all processes attached to the debugger.
  kProcess,  // Stop all threads of the process that hit the breakpoint.
  kThread,   // Stop only the thread that hit the breakpoint.
  kNone      // Don't stop anything but accumulate hit counts.
};

// NOTE: read-only could be added in the future as arm64 supports them. They're not added today as
//       x64 does not support them and presenting a common platform is cleaner for now.
enum class BreakpointType : uint32_t {
  kSoftware = 0,  // Software code execution.
  kHardware,      // Hardware code execution.
  kReadWrite,     // Hardware read/write.
  kWrite,         // Hardware write.

  kLast,  // Not a real type, end marker.
};
const char* BreakpointTypeToString(BreakpointType);

// Read, ReadWrite and Write are considered watchpoint types.
bool IsWatchpointType(BreakpointType);

constexpr uint32_t kDebugAgentInternalBreakpointId = static_cast<uint32_t>(-1);

struct BreakpointSettings {
  // The ID if this breakpoint. This is assigned by the client. This is different than the ID in
  // the console frontend which can be across mutliple processes or may match several addresses in
  // a single process.
  //
  // The ID kDebugAgentInternalBreakpointId is reserved for internal use by the backend.
  uint32_t id = 0;

  BreakpointType type = BreakpointType::kSoftware;

  // Name used to recognize a breakpoint. Useful for debugging purposes. Optional.
  std::string name;

  // When set, the breakpoint will automatically be removed as soon as it is
  // hit.
  bool one_shot = false;

  // What should stop when the breakpoint is hit.
  Stop stop = Stop::kAll;

  // Processes to which this breakpoint applies.
  //
  // If any process specifies a nonzero thread_koid, it must be the only process (a breakpoint can
  // apply either to all threads in a set of processes, or exactly one thread globally).
  std::vector<ProcessBreakpointSettings> locations;
};

struct BreakpointStats {
  uint32_t id = 0;
  uint32_t hit_count = 0;

  // On a "breakpoint hit" message from the debug agent, if this flag is set,
  // the agent has deleted the breakpoint because it was a one-shot breakpoint.
  // Whenever a client gets a breakpoint hit with this flag set, it should
  // clear the local state associated with the breakpoint.
  bool should_delete = false;
};

// Information on one loaded module.
struct Module {
  std::string name;            // The main executable binary will normally have an empty name.
  uint64_t base = 0;           // Load address of this file.
  uint64_t debug_address = 0;  // Link map address for this module.
  std::string build_id;
};

struct AddressRegion {
  std::string name;
  uint64_t base;
  uint64_t size;
  uint64_t depth;
};

// ReadRegisters -----------------------------------------------------------------------------------

struct ConfigAction {
  enum class Type : uint32_t {
    // Quit whenever the connection shutdowns.
    kQuitOnExit,  // Values are "false" | "true"

    kLast,  // Not valid.
  };
  static const char* TypeToString(Type);

  Type type = Type::kLast;

  // Each action uses a different set of values.
  std::string value;
};

// LoadInfoHandleTable -----------------------------------------------------------------------------

// VMO-specific handle information from zx_info_vmo that's not in the InfoHandle structure.
struct InfoHandleVmo {
  char name[32];  // Needs to be POD for use in union below, and 32 is the max from the kernel.
  uint64_t size_bytes;
  uint64_t parent_koid;
  uint64_t num_children;
  uint64_t num_mappings;
  uint64_t share_count;
  uint32_t flags;
  uint64_t committed_bytes;
  uint32_t cache_policy;
  uint64_t metadata_bytes;
  uint64_t committed_change_events;
};

// This structure is assumed to be entirely POD.
struct InfoHandle {
  // Provide 0-init that covers the union.
  InfoHandle() { memset(this, 0, sizeof(InfoHandle)); }

  // Standard information from zx_info_handle_extended.
  //
  // There is a special case for a VMO. It is possible to have a VMO mapped without a handle to it.
  // These will appear here but the handle_value will be 0.
  uint32_t type;
  uint32_t handle_value;
  uint32_t rights;
  uint32_t reserved;
  uint64_t koid;
  uint64_t related_koid;
  uint64_t peer_owner_koid;

  // Type-specific handle information.
  union {
    InfoHandleVmo vmo;  // Valid when type == ZX_OBJ_TYPE_VMO.
    // Other types go here.
  } ext;
};

#pragma pack(pop)

}  // namespace debug_ipc

#endif  // SRC_DEVELOPER_DEBUG_IPC_RECORDS_H_
