// 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 <lib/fit/function.h>
#include <src/lib/fxl/macros.h>
#include <lib/zx/process.h>
#include <lib/zx/suspend_token.h>
#include <lib/zx/time.h>
#include <zircon/syscalls/exception.h>
#include <zircon/types.h>

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

#include "breakpoint.h"
#include "delegate.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:
  enum class State { kNew, kStarting, kRunning, kGone };

  using StartCallback = fit::function<zx_status_t(Process*)>;

  // This value is used as the return code if something prevents us from
  // obtaining it from the process.
  static constexpr int kDefaultFailureReturnCode = -1;

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

  explicit Process(Server* server, Delegate* delegate_);
  ~Process();

  std::string GetName() const;

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

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

  int return_code() const { return return_code_; }
  bool return_code_is_set() const { return return_code_is_set_; }

  // Initialize a new inferior process that was built using |ProcessBuilder|.
  // Returns false if there is an error.
  // Do not call this if the process is currently live (state is kStarting or
  // kRunning).
  bool InitializeFromBuilder(std::unique_ptr<process::ProcessBuilder> builder);

  // Attach to newly created process |process|.
  // |start_callback| is called by |Start()| to start execution of the process.
  bool AttachToNew(zx::process process, StartCallback start_callback);

  // Attach to running program |process|.
  // Returns false if there is an error.
  // Do not call this if the process is currently live (state is kStarting or
  // kRunning).
  bool AttachToRunning(zx::process process);

  // 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.
  // N.B. It is the caller's responsibility to have first removed any and all
  // breakpoints. This includes the ld.so breakpoint which is automagically
  // set if we launched the inferior. Furthermore, if the ld.so breakpoint
  // hasn't been hit yet, which can be determined by calling
  // |ldso_debug_data_has_initialized()|, then this must be called while the
  // inferior is stopped. Typically this happens when processing the
  // THREAD_STARTING exception for the initial thread.
  bool Detach();

  // Starts running the process. Returns false in case of an error.
  // |AttachToNew()| MUST be called successfully before calling Start().
  // |InitializeFromBuilder| does this implicitly.
  bool Start();

  // Terminate the process.
  // This doesn't wait for the process to die. The server loop will get a
  // ZX_PROCESS_TERMINATED signal when that happens.
  bool Kill();

  // Request all threads in the process to suspend.
  // This doesn't wait for them to suspend, just requests it.
  // It is up to the app's server loop to wait for threads to suspend if
  // it wants to.
  bool RequestSuspend();

  // Resume the process after having been suspended.
  void ResumeFromSuspension();

  // 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.
  const zx::process& process() const { return process_; }

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

  Server* server() { return server_; }

  Delegate* delegate() const { return delegate_; }

  // 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.
  // This may not be called while detached.
  void EnsureThreadMapFresh();

  // 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::kGone 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);

  bool attached_running() const { return attached_running_; }

  // See if the list of loaded dsos has been built, and if not build it.
  // This is called when |thread| is stopped at s/w breakpoints (and thus
  // potentially dynamic linker breakpoints).
  // Returns true if the thread was stopped at a dynamic linker breakpoint,
  // and thus the caller should immediately resume the thread.
  bool CheckDsosList(Thread* thread);

  // 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();

  // Called when ZX_PROCESS_TERMINATED is received, update our internal state.
  void OnTermination();

  // Print an Inspector-style dump of each thread.
  // Threads that are not currently in an exception or suspended are ignored.
  // It is the caller's responsibility to stop desired threads first (and wait
  // for them to stop).
  void Dump();

  zx_vaddr_t debug_addr_property() const { return debug_addr_property_; }

  bool ldso_debug_data_has_initialized() const {
    return ldso_debug_data_has_initialized_;
  }

  zx_vaddr_t ldso_debug_break_addr() const { return ldso_debug_break_addr_; }

  zx_vaddr_t ldso_debug_map_addr() const { return ldso_debug_map_addr_; }

 private:
  // When refreshing the thread list, new threads could be created.
  // Add this to the number of existing threads to account for new ones.
  // The number is large but the cost is only 8 bytes per extra thread for
  // the thread's koid.
  static constexpr size_t kNumExtraRefreshThreads = 20;

  // When refreshing the thread list, if threads are being created faster than
  // we can keep up, keep looking, but don't keep trying forever.
  static constexpr size_t kRefreshThreadsTryCount = 4;

  // Refreshes the complete Thread list for this process. Returns false if an
  // error is returned from a syscall. Any threads that were accumulated up to
  // that point are retained.
  // Pointers to existing threads are maintained.
  void RefreshAllThreads();

  // Wrapper on |zx_object_get_property()| to fetch the value of
  // ZX_PROP_PROCESS_DEBUG_ADDR.
  // Returns a boolean indicating success.
  bool GetDebugAddrProperty(zx_vaddr_t* out_debug_addr);

  // Wrapper on |zx_object_set_property()| to set the value of
  // ZX_PROP_PROCESS_DEBUG_ADDR.
  // Returns a boolean indicating success.
  bool SetDebugAddrProperty(zx_vaddr_t debug_addr);

  // Cause ld.so to execute a s/w breakpoint instruction after all dsos have
  // been loaded at startup. Returns true on success.
  bool SetLdsoDebugTrigger();

  // Fetch the value of ZX_PROP_PROCESS_DEBUG_ADDR.
  // Returns true the value if it has been set (by the dynamic linker) or
  // zero if it has not been set yet (or there's an error).
  // The value is cached in |debug_addr_|.
  zx_vaddr_t GetDebugAddr();

  // Assuming the inferior is stopped at a s/w breakpoint, check if it's
  // stopped at the ZX_PROCESS_DEBUG_ADDR_BREAK_ON_SET breakpoint.
  // If so, update |ldso_debug_break_addr_| and
  // |seen_ldso_debug_addr_break_| and return true.
  // Otherwise return false.
  bool CheckLdsoDebugAddrBreak();

  // Try to build the list of loaded dsos.
  // This must be called at a point where it is safe to read the list.
  void TryBuildLoadedDsosList(Thread* thread);

  // The exception handler invoked by ExceptionPort.
  // TODO(dje): Friend is temporary, pending completion of the refactor moving
  // the exception/signal handler to |Server|.
  friend class Server;
  void OnExceptionOrSignal(const zx_port_packet_t& packet);

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

  // Helper routine to implement |AttachToNew(),AttachToRunning()|.
  bool AttachWorker(zx::process process, bool attach_running);

  // 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.
  // This does not clear |id_|, that is still retrievable after the process
  // has terminated.
  void Clear();

  // Record new thread |thread_handle,thread_id|.
  Thread* AddThread(zx_handle_t thread_handle, zx_koid_t thread_id);

  // Record the process's return code.
  void RecordReturnCode();

  // The server that owns us (non-owning).
  Server* server_;

  // The delegate that we send life-cycle notifications to (non-owning).
  Delegate* delegate_;

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

  // The debug-capable handle that we use to invoke zx_debug_* syscalls.
  zx::process process_;

  // 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 value of ZX_PROP_PROCESS_DEBUG_ADDR or zero if not known yet.
  // The value is never legitimately zero, except if we attached to a running
  // program prior to ld.so reaching its debug breakpoint on startup.
  zx_vaddr_t debug_addr_property_ = 0;

  // True if ld.so's debug data structures are initialized.
  bool ldso_debug_data_has_initialized_ = false;

  // The address of the "standard" dynamic linker breakpoint.
  // I.e., the contents of |r_debug.r_brk|.
  // Zero if not known yet.
  zx_vaddr_t ldso_debug_break_addr_ = 0;

  // The address of the dynamic linker's list of loaded shared libraries.
  // I.e., the contents of |r_debug.r_map|.
  // Zero if not known yet.
  zx_vaddr_t ldso_debug_map_addr_ = 0;

  // 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;

  // True if the debugging exception port has been bound.
  bool eport_bound_ = false;

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

  // This callback is invoked by |Start()|.
  StartCallback start_callback_;

  // Suspend token when entire process is suspended.
  zx::suspend_token suspend_token_;

  // 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 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.
  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;

  // Processes are detached from when they exit.
  // Save the return code for later testing.
  int return_code_ = kDefaultFailureReturnCode;
  bool return_code_is_set_ = false;

  FXL_DISALLOW_COPY_AND_ASSIGN(Process);
};

}  // namespace inferior_control

#endif  // GARNET_LIB_INFERIOR_CONTROL_PROCESS_H_
