// Copyright 2016 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 GARNET_LIB_INFERIOR_CONTROL_PROCESS_H_
#define GARNET_LIB_INFERIOR_CONTROL_PROCESS_H_

#include <memory>
#include <string>
#include <unordered_map>

#include <zircon/syscalls/exception.h>
#include <zircon/types.h>

#include "garnet/lib/debugger_utils/dso_list.h"
#include "garnet/lib/debugger_utils/util.h"
#include "garnet/lib/process/process_builder.h"
#include "lib/fxl/macros.h"

#include "breakpoint.h"
#include "exception_port.h"
#include "memory_process.h"
#include "thread.h"

namespace inferior_control {

class Server;
class Thread;

// Represents an inferior process that we're attached to.
class Process final {
 public:
 public:
  enum class State { kNew, kStarting, kRunning, kGone };

  // Delegate interface for listening to Process life-time events.
  class Delegate {
   public:
    virtual ~Delegate() = default;

    // Called when a new thread that is part of this process has been started.
    // This is indicated by ZX_EXCP_THREAD_STARTING.
    virtual void OnThreadStarting(Process* process, Thread* thread,
                                  const zx_exception_context_t& context) = 0;

    // Called when |thread| has exited (ZX_EXCP_THREAD_EXITING).
    virtual void OnThreadExiting(Process* process, Thread* thread,
                                 const zx_exception_context_t& context) = 0;

    // Called when |process| has exited.
    virtual void OnProcessExit(Process* process) = 0;

    // Called when the kernel reports an architectural exception.
    virtual void OnArchitecturalException(
        Process* process, Thread* thread, const zx_excp_type_t type,
        const zx_exception_context_t& context) = 0;

    // Called when |thread| has gets a synthetic exception
    // (e.g., ZX_EXCP_POLICY_ERROR) that is akin to an architectural
    // exception: the program got an error and by default crashes.
    virtual void OnSyntheticException(
        Process* process, Thread* thread, const zx_excp_type_t type,
        const zx_exception_context_t& context) = 0;
  };

  explicit Process(Server* server, Delegate* delegate_,
                   std::shared_ptr<component::Services> services);
  ~Process();

  std::string GetName() const;

  // Note: This includes the program in |argv[0]|.
  const debugger_utils::Argv& argv() { return argv_; }
  void set_argv(const debugger_utils::Argv& argv) { argv_ = argv; }

  // Add extra handles to the process.
  //
  // Must be called before |Initialize|.
  void AddStartupHandle(fuchsia::process::HandleInfo handle);

  // Returns the current state of this process.
  State state() const { return state_; }

  // Change the state to |new_state|.
  void set_state(State new_state);

  static const char* StateName(Process::State state);

  // Creates and initializes the inferior process, via ProcessBuilder, but does
  // not start it. set_argv() must have already been called.
  // This also "attaches" to the inferior: A debug-capable process handle is
  // obtained and the debugger exception port is bound to.
  // Returns false if there is an error.
  // Do not call this if the process is currently live (state is kStarting or
  // kRunning).
  bool Initialize();

  // Attach to running program with pid |pid|.
  // A debug-capable process handle is obtained and the debugger exception
  // port is bound to.
  // Returns false if there is an error.
  // Do not call this if the process is currently live (state is kStarting or
  // kRunning).
  bool Attach(zx_koid_t pid);

  // Detach from an attached process, and return to pre-attached state.
  // This includes unbinding from the exception port and closing the process
  // handle. To keep things simple and clean "detach" means "release all
  // connections with the inferior". After detaching we should have absolutely
  // no effect on the inferior, including not preserving the lifetime of the
  // kernel process instance because we still have a handle of the process.
  // Returns true on success, or false if already detached.
  bool Detach();

  // Starts running the process. Returns false in case of an error.
  // Initialize() MUST be called successfully before calling Start().
  bool Start();

  // Terminate the process.
  bool Kill();

  // Returns true if the process is running or has been running.
  bool IsLive() const;

  // Returns true if the process is currently attached.
  bool IsAttached() const;

  // Returns the process handle. This handle is owned and managed by this
  // Process instance, thus the caller should not close the handle.
  zx_handle_t handle() const { return handle_; }

  // Returns the process ID.
  zx_koid_t id() const { return id_; }

  Server* server() { return server_; }

  // Returns a mutable handle to the set of breakpoints managed by this process.
  ProcessBreakpointSet* breakpoints() { return &breakpoints_; }

  // Returns the base load address of the dynamic linker.
  zx_vaddr_t base_address() const { return base_address_; }

  // Returns the entry point of the dynamic linker.
  zx_vaddr_t entry_address() const { return entry_address_; }

  // Returns the thread with the thread ID |thread_id| that's owned by this
  // process. Returns nullptr if no such thread exists. The returned pointer is
  // owned and managed by this Process instance.
  Thread* FindThreadById(zx_koid_t thread_id);

  // Returns an arbitrary thread that is owned by this process. This picks the
  // first thread that is returned from zx_object_get_info for the
  // ZX_INFO_PROCESS_THREADS topic. This will refresh all threads.
  // TODO(dje): ISTR GNU gdbserver being more random to avoid starving threads.
  Thread* PickOneThread();

  // If the thread map might be stale, refresh it.
  void EnsureThreadMapFresh();

  // Refreshes the complete Thread list for this process. Returns false if an
  // error is returned from a syscall.
  bool RefreshAllThreads();

  // Iterates through all cached threads and invokes |callback| for each of
  // them. |callback| is guaranteed to get called only before ForEachThread()
  // returns, so it is safe to bind local variables to |callback|.
  using ThreadCallback = fit::function<void(Thread*)>;
  void ForEachThread(const ThreadCallback& callback);
  // Same as ForEachThread except ignores State::Gone threads.
  void ForEachLiveThread(const ThreadCallback& callback);

  // Reads the block of memory of length |length| bytes starting at address
  // |address| into |out_buffer|. |out_buffer| must be at least as large as
  // |length|. Returns true on success or false on failure.
  bool ReadMemory(uintptr_t address, void* out_buffer, size_t length);

  // Writes the block of memory of length |length| bytes from |data| to the
  // memory address |address| of this process. Returns true on success or false
  // on failure.
  bool WriteMemory(uintptr_t address, const void* data, size_t length);

  // Fetch the process's exit code.
  int ExitCode();

  bool attached_running() const { return attached_running_; }

  // Build list of loaded dsos.
  // This must be called at a point where it is safe to read the list.
  // If |check_ldso_bkpt| is true then verify |thread| is stopped at the
  // dynamic linker breakpoint. If not then skip trying. Otherwise |thread|
  // must be nullptr.
  // TODO(dje): Maybe just pass |thread|, later.
  // TODO(dje): For the rsp server this is only called once, after the main
  // executable has been loaded. Therefore this list will not contain
  // subsequently loaded dsos.
  void TryBuildLoadedDsosList(Thread* thread, bool check_ldso_bkpt);

  // Return true if dsos, including the main executable, have been loaded
  // into the inferior.
  bool DsosLoaded() { return dsos_ != nullptr; }

  // Return list of loaded dsos.
  // Returns nullptr if none loaded yet or loading failed.
  // TODO(dje): constness wip
  debugger_utils::dsoinfo_t* GetDsos() const { return dsos_; }

  // Return the DSO for |pc| or nullptr if none.
  // TODO(dje): Result is not const for debug file lookup support.
  debugger_utils::dsoinfo_t* LookupDso(zx_vaddr_t pc) const;

  // Return the entry for the main executable from the dsos list.
  // Returns nullptr if not present (could happen if inferior data structure
  // has been clobbered).
  const debugger_utils::dsoinfo_t* GetExecDso();

 private:
  // The exception handler invoked by ExceptionPort.
  void OnExceptionOrSignal(const zx_port_packet_t& packet,
                           const zx_exception_context_t& context);

  // Debug handle mgmt.
  bool AllocDebugHandle(process::ProcessBuilder* builder);
  bool AllocDebugHandle(zx_koid_t pid);
  void CloseDebugHandle();

  // Exception port mgmt.
  bool BindExceptionPort();
  void UnbindExceptionPort();

  // Detach from the inferior, but don't clear out any data structures.
  void RawDetach();

  // Release all resources held by the process.
  // Called after all other processing of a process exit has been done.
  void Clear();

  // The server that owns us.
  Server* server_;  // weak

  // The delegate that we send life-cycle notifications to.
  Delegate* delegate_;  // weak

  // Handle containing services available to this process.
  std::shared_ptr<component::Services> services_;

  // The argv that this process was initialized with.
  debugger_utils::Argv argv_;

  // Extra handles to pass to process during creation.
  std::vector<fuchsia::process::HandleInfo> extra_handles_;

  // The process::ProcessBuilder instance used to bootstrap and run the process.
  std::unique_ptr<process::ProcessBuilder> builder_;

  // The debug-capable handle that we use to invoke zx_debug_* syscalls.
  zx_handle_t handle_ = ZX_HANDLE_INVALID;

  // The current state of this process.
  State state_ = State::kNew;

  // The process ID (also the kernel object ID).
  zx_koid_t id_ = ZX_KOID_INVALID;

  // The base load address of the dynamic linker.
  zx_vaddr_t base_address_ = 0;

  // The entry point of the dynamic linker.
  zx_vaddr_t entry_address_ = 0;

  // The key we receive after binding an exception port.
  ExceptionPort::Key eport_key_ = 0;

  // True if we attached, or will attach, to a running program.
  // Otherwise we're launching a program from scratch.
  bool attached_running_ = false;

  // The API to access memory.
  std::shared_ptr<debugger_utils::ByteBlock> memory_;

  // The collection of breakpoints that belong to this process.
  ProcessBreakpointSet breakpoints_;

  // The threads owned by this process. This is map is populated lazily when
  // threads are requested through FindThreadById(). It can also be repopulated
  // from scratch, e.g., when attaching to an already running program.
  using ThreadMap = std::unordered_map<zx_koid_t, std::unique_ptr<Thread>>;
  ThreadMap threads_;

  // If true then |threads_| needs to be recalculated from scratch.
  bool thread_map_stale_ = false;

  // List of dsos loaded.
  // NULL if none have been loaded yet (including main executable).
  // TODO(dje): Code taking from crashlogger, to be rewritten.
  // TODO(dje): Doesn't include dsos loaded later.
  debugger_utils::dsoinfo_t* dsos_ = nullptr;

  // If true then building the dso list failed, don't try again.
  bool dsos_build_failed_ = false;

  FXL_DISALLOW_COPY_AND_ASSIGN(Process);
};

}  // namespace inferior_control

#endif  // GARNET_LIB_INFERIOR_CONTROL_PROCESS_H_
