// 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_DEBUG_AGENT_DEBUGGED_PROCESS_H_
#define SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_PROCESS_H_

#include <map>
#include <memory>
#include <vector>

#include <fbl/unique_fd.h>

#include "src/developer/debug/debug_agent/debugged_thread.h"
#include "src/developer/debug/debug_agent/module_list.h"
#include "src/developer/debug/debug_agent/process_handle.h"
#include "src/developer/debug/debug_agent/process_handle_observer.h"
#include "src/developer/debug/ipc/protocol.h"
#include "src/developer/debug/shared/buffered_zx_socket.h"
#include "src/developer/debug/shared/message_loop.h"
#include "src/lib/fxl/macros.h"

namespace debug_agent {

class Breakpoint;
class DebugAgent;
class HardwareBreakpoint;
class ProcessBreakpoint;
class ProcessWatchpoint;
class SoftwareBreakpoint;
class Watchpoint;

struct DebuggedProcessCreateInfo {
  explicit DebuggedProcessCreateInfo(std::unique_ptr<ProcessHandle> handle);

  // Required.
  std::unique_ptr<ProcessHandle> handle;

  // Optional.
  zx::socket out;  // stdout.
  zx::socket err;  // stderr.

  // Whether this process was obtained via a process limbo.
  // This is relevant when attempting to kill the process, as handles obtained via the limbo do not
  // have the ZX_RIGHT_DESTROY right. The way to "kill" them is to re send them to the limbo and
  // then release it from it.
  bool from_limbo = false;
};

class DebuggedProcess : public ProcessHandleObserver {
 public:
  using WatchpointMap = std::map<debug_ipc::AddressRange, std::unique_ptr<Watchpoint>,
                                 debug_ipc::AddressRangeBeginCmp>;

  // Caller must call Init immediately after construction and delete the
  // object if that fails.
  DebuggedProcess(DebugAgent*, DebuggedProcessCreateInfo&&);
  virtual ~DebuggedProcess();

  zx_koid_t koid() const { return process_handle_->GetKoid(); }
  DebugAgent* debug_agent() const { return debug_agent_; }

  const ProcessHandle& process_handle() const { return *process_handle_; }
  ProcessHandle& process_handle() { return *process_handle_; }

  // TODO(brettw) remove this and have all callers use thread_handle().
  zx::process& handle() { return process_handle_->GetNativeHandle(); }
  const zx::process& handle() const { return process_handle_->GetNativeHandle(); }

  const ModuleList& module_list() const { return module_list_; }

  // Returns true on success. On failure, the object may not be used further.
  zx_status_t Init();

  // IPC handlers.
  void OnPause(const debug_ipc::PauseRequest& request, debug_ipc::PauseReply* reply);
  void OnResume(const debug_ipc::ResumeRequest& request);
  void OnReadMemory(const debug_ipc::ReadMemoryRequest& request, debug_ipc::ReadMemoryReply* reply);
  void OnKill(const debug_ipc::KillRequest& request, debug_ipc::KillReply* reply);
  void OnAddressSpace(const debug_ipc::AddressSpaceRequest& request,
                      debug_ipc::AddressSpaceReply* reply);
  void OnModules(debug_ipc::ModulesReply* reply);
  void OnWriteMemory(const debug_ipc::WriteMemoryRequest& request,
                     debug_ipc::WriteMemoryReply* reply);
  void OnLoadInfoHandleTable(const debug_ipc::LoadInfoHandleTableRequest& request,
                             debug_ipc::LoadInfoHandleTableReply* reply);

  void InjectThreadForTest(std::unique_ptr<DebuggedThread> thread);

  // Synchronously pauses all threads in the process from the perspective of the client. This issues
  // ClientSuspend() on all threads (see that for more on what "client" means).
  void ClientSuspendAllThreads();

  // Returns the thread or null if there is no known thread for this koid.
  DebuggedThread* GetThread(zx_koid_t thread_koid) const;
  std::vector<DebuggedThread*> GetThreads() const;

  // Populates the thread map with the current threads for this process.
  // This function does not notify the client of thread start, but rather updates the internal
  // thread state according to the underlying zircon truth.
  void PopulateCurrentThreads();

  // Returns the information for all current threads. This gets minimal stacks.
  std::vector<debug_ipc::ThreadRecord> GetThreadRecords() const;

  // Checks if this breakpoint is a special internal one. If it is, handles it and returns true.
  // If it's not special, does nothing and returns false. The parameter indicates the breakpoint
  // that was hit. If the breakpoint was a hardcoded one, the parameter should be null.
  //
  // This will check for the different types of loader breakpoints.
  enum class SpecialBreakpointResult { kNotSpecial, kContinue, kKeepSuspended };
  SpecialBreakpointResult HandleSpecialBreakpoint(ProcessBreakpoint* optional_bp);

  // If the process can know its modules, suspend all thread and send the module list. This does not
  // refresh the module list.
  //
  // This is used in the case where we attach to an existing process or a new forked process and the
  // debug address is known. The client expects the threads to be suspended so it can resolve
  // breakpoints and resume them.
  virtual void SuspendAndSendModulesIfKnown();

  // Looks for breakpoints at the given address. Null if no breakpoints are at that address.
  virtual SoftwareBreakpoint* FindSoftwareBreakpoint(uint64_t address) const;
  virtual HardwareBreakpoint* FindHardwareBreakpoint(uint64_t address) const;
  virtual Watchpoint* FindWatchpoint(const debug_ipc::AddressRange&) const;

  zx_status_t RegisterBreakpoint(Breakpoint* bp, uint64_t address);
  void UnregisterBreakpoint(Breakpoint* bp, uint64_t address);

  zx_status_t RegisterWatchpoint(Breakpoint* bp, const debug_ipc::AddressRange& range);
  void UnregisterWatchpoint(Breakpoint* bp, const debug_ipc::AddressRange& range);

  // Each time a thread attempts to step over a breakpoint, the breakpoint will enqueue itself and
  // the thread into the step over queue. The step over queue is used so that there is only one
  // breakpoint being stepped over at a time.
  //
  // Enqueuing the breakpoint does not mean that the step over begins immediately, but rather the
  // process will call the |ExecuteStepOver| method on the breakpoint once its turn has come up in
  // the queue.
  //
  // In some error cases this might happen twice for the same thread. For example, if there is an
  // error clearing the breakpoint instruction, attempting to clear it and then single-step it will
  // just hit the same breakpoint again and the "step over" will never complete.
  //
  // If this happens the original "step over" request will be silently dropped. Otherwise, the
  // step queue will be recursively waiting for itself and can never continue. All other breakpoints
  // will still be waiting behind this failed step, but at least it could theoretically continue if
  // the breakpoint clearing works in a future try.
  void EnqueueStepOver(ProcessBreakpoint* process_breakpoint, DebuggedThread* thread);

  // Called by the currently stepping over breakpoint when it's done. It will execute the next
  // enqueued breakpoint. If there are no more breakpoints enqueued, this will let all the
  // breakpoints know so that it can resume the stepped over threads.
  void OnBreakpointFinishedSteppingOver();

  // Queue of breakpoints that are currently being stepped over.
  //
  // As stepping over requires suspending all the threads, doing multiple at a time has a fair
  // chance of introducing deadlocks. We use this queue to serialize the stepping over, so only
  // one process breakpoint is being stepped over at a time.
  struct StepOverTicket {
    fxl::WeakPtr<ProcessBreakpoint> process_breakpoint;
    fxl::WeakPtr<DebuggedThread> thread;

    bool is_valid() const { return !!process_breakpoint && !!thread; }
  };
  const std::deque<StepOverTicket>& step_over_queue() const { return step_over_queue_; }

  const std::map<uint64_t, std::unique_ptr<SoftwareBreakpoint>>& software_breakpoints() const {
    return software_breakpoints_;
  }

  const std::map<uint64_t, std::unique_ptr<HardwareBreakpoint>>& hardware_breakpoints() const {
    return hardware_breakpoints_;
  }

  const WatchpointMap& watchpoints() const { return watchpoints_; }

  bool from_limbo() const { return from_limbo_; }

 private:
  // ProcessHandleObserver implementation.
  void OnProcessTerminated() override;
  void OnThreadStarting(std::unique_ptr<ExceptionHandle> exception) override;
  void OnThreadExiting(std::unique_ptr<ExceptionHandle> exception) override;
  void OnException(std::unique_ptr<ExceptionHandle> exception) override;

  void OnStdout(bool close);
  void OnStderr(bool close);

  // Sends the currently loaded modules to the client with the current list of threads. This does
  // not refresh the module cache. All threads are assumed to be paused before this call.
  void SendModuleNotification();

  // Sends a IO notification over to the client.
  void SendIO(debug_ipc::NotifyIO::Type, const std::vector<char>& data);

  // This function will gracefully detach from the underlying zircon process.
  // Detaching correctly requires several steps:
  //
  // 1. Remove the installed breakpoints.
  //
  // 2. Resume threads from the exception. Only threads that are stopped on an
  // exception should be resumed. This is because otherwise zircon will treat
  // this exception as unhandled and will bubble up the exception upwards,
  // probably resulting in a crash.
  //
  // 3. Unbind the exception port.
  void DetachFromProcess();

  // Deletes any elements in the step over queue that are no longer valid. This happens when either
  // the thread or the breakpoint went away while the ticket was waiting within the queue.
  //
  // If the |thread| parameter is non-null, ALL requests from that thread will be deleted in
  // addition to the normal pruning behavior.
  void PruneStepOverQueue(DebuggedThread* optional_thread);

  // Attempts to load the debug_state_ value from the
  // ZX_PROP_PROCESS_DEBUG_ADDR of the debugged process. Returns true if it
  // is now set. False means it remains unset. Normally the first time this
  // returns true would need to be followed up with a SendModuleNotification.
  bool RegisterDebugState();

  zx_status_t RegisterSoftwareBreakpoint(Breakpoint* bp, uint64_t address);
  void UnregisterSoftwareBreakpoint(Breakpoint* bp, uint64_t address);
  zx_status_t RegisterHardwareBreakpoint(Breakpoint* bp, uint64_t address);
  void UnregisterHardwareBreakpoint(Breakpoint* bp, uint64_t address);

  DebugAgent* debug_agent_ = nullptr;  // Non-owning.

  std::unique_ptr<ProcessHandle> process_handle_;

  // Address in the debugged program of the dl_debug_state in ld.so.
  uint64_t dl_debug_addr_ = 0;

  // Current modules loaded in the process.
  ModuleList module_list_;

  // Breakpoint used to catch shared library loads. This will be set when the dl_debug_addr_ is
  // known.
  std::unique_ptr<Breakpoint> loader_breakpoint_;

  std::map<zx_koid_t, std::unique_ptr<DebuggedThread>> threads_;

  // Maps addresses to the ProcessBreakpoint at a location.
  std::map<uint64_t, std::unique_ptr<SoftwareBreakpoint>> software_breakpoints_;
  std::map<uint64_t, std::unique_ptr<HardwareBreakpoint>> hardware_breakpoints_;
  WatchpointMap watchpoints_;

  std::deque<StepOverTicket> step_over_queue_;

  debug_ipc::BufferedZxSocket stdout_;
  debug_ipc::BufferedZxSocket stderr_;

  // Whether this process was obtained from limbo or not. The agent will check this information
  // when it tries to kill this process in order to determine whether the ZX_ERR_BAD_ACCESS is
  // expected (limbo handles do not have ZX_RIGHT_DESTROY right) or it is an actual error.
  bool from_limbo_ = false;

  FXL_DISALLOW_COPY_AND_ASSIGN(DebuggedProcess);
};

}  // namespace debug_agent

#endif  // SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_PROCESS_H_
