11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_DEBUG_WASM_GDB_SERVER_TARGET_H_
61cb0ef41Sopenharmony_ci#define V8_DEBUG_WASM_GDB_SERVER_TARGET_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <atomic>
91cb0ef41Sopenharmony_ci#include <map>
101cb0ef41Sopenharmony_ci#include "src/base/macros.h"
111cb0ef41Sopenharmony_ci#include "src/debug/wasm/gdb-server/gdb-remote-util.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace internal {
151cb0ef41Sopenharmony_cinamespace wasm {
161cb0ef41Sopenharmony_cinamespace gdb_server {
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciclass GdbServer;
191cb0ef41Sopenharmony_ciclass Packet;
201cb0ef41Sopenharmony_ciclass Session;
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci// Class Target represents a debugging target. It contains the logic to decode
231cb0ef41Sopenharmony_ci// incoming GDB-remote packets, execute them forwarding the debugger commands
241cb0ef41Sopenharmony_ci// and queries to the Wasm engine, and send back GDB-remote packets.
251cb0ef41Sopenharmony_ciclass Target {
261cb0ef41Sopenharmony_ci public:
271cb0ef41Sopenharmony_ci  // Contruct a Target object.
281cb0ef41Sopenharmony_ci  explicit Target(GdbServer* gdb_server);
291cb0ef41Sopenharmony_ci  Target(const Target&) = delete;
301cb0ef41Sopenharmony_ci  Target& operator=(const Target&) = delete;
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  // This function spin on a debugging session, until it closes.
331cb0ef41Sopenharmony_ci  void Run(Session* ses);
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  void Terminate();
361cb0ef41Sopenharmony_ci  bool IsTerminated() const { return status_ == Status::Terminated; }
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  // Notifies that the debuggee thread suspended at a breakpoint.
391cb0ef41Sopenharmony_ci  void OnProgramBreak(Isolate* isolate,
401cb0ef41Sopenharmony_ci                      const std::vector<wasm_addr_t>& call_frames);
411cb0ef41Sopenharmony_ci  // Notifies that the debuggee thread suspended because of an unhandled
421cb0ef41Sopenharmony_ci  // exception.
431cb0ef41Sopenharmony_ci  void OnException(Isolate* isolate,
441cb0ef41Sopenharmony_ci                   const std::vector<wasm_addr_t>& call_frames);
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  // Returns the state at the moment of the thread suspension.
471cb0ef41Sopenharmony_ci  const std::vector<wasm_addr_t> GetCallStack() const;
481cb0ef41Sopenharmony_ci  wasm_addr_t GetCurrentPc() const;
491cb0ef41Sopenharmony_ci  Isolate* GetCurrentIsolate() const { return current_isolate_; }
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci private:
521cb0ef41Sopenharmony_ci  void OnSuspended(Isolate* isolate, int signal,
531cb0ef41Sopenharmony_ci                   const std::vector<wasm_addr_t>& call_frames);
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  // Initializes a map used to make fast lookups when handling query packets
561cb0ef41Sopenharmony_ci  // that have a constant response.
571cb0ef41Sopenharmony_ci  void InitQueryPropertyMap();
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  // Blocks waiting for one of these two events to occur:
601cb0ef41Sopenharmony_ci  // - A network packet arrives from the debugger, or the debugger connection is
611cb0ef41Sopenharmony_ci  //   closed;
621cb0ef41Sopenharmony_ci  // - The debuggee suspends execution because of a trap or breakpoint.
631cb0ef41Sopenharmony_ci  void WaitForDebugEvent();
641cb0ef41Sopenharmony_ci  void ProcessDebugEvent();
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  // Processes GDB-remote packets that arrive from the debugger.
671cb0ef41Sopenharmony_ci  // This method should be called when the debuggee has suspended its execution.
681cb0ef41Sopenharmony_ci  void ProcessCommands();
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  // Requests that the thread suspends execution at the next Wasm instruction.
711cb0ef41Sopenharmony_ci  void Suspend();
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  enum class ErrorCode { None = 0, BadFormat = 1, BadArgs = 2, Failed = 3 };
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci  enum class ProcessPacketResult {
761cb0ef41Sopenharmony_ci    Paused,    // The command was processed, debuggee still paused.
771cb0ef41Sopenharmony_ci    Continue,  // The debuggee should resume execution.
781cb0ef41Sopenharmony_ci    Detach,    // Request to detach from the debugger.
791cb0ef41Sopenharmony_ci    Kill       // Request to terminate the debuggee process.
801cb0ef41Sopenharmony_ci  };
811cb0ef41Sopenharmony_ci  // This function always succeedes, since all errors are reported as an error
821cb0ef41Sopenharmony_ci  // string "Exx" where xx is a two digit number.
831cb0ef41Sopenharmony_ci  // The return value indicates if the target can resume execution or it is
841cb0ef41Sopenharmony_ci  // still paused.
851cb0ef41Sopenharmony_ci  ProcessPacketResult ProcessPacket(Packet* pkt_in, Packet* pkt_out);
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  // Processes a general query packet
881cb0ef41Sopenharmony_ci  ErrorCode ProcessQueryPacket(const Packet* pkt_in, Packet* pkt_out);
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  // Formats a 'Stop-reply' packet, which is sent in response of a 'c'
911cb0ef41Sopenharmony_ci  // (continue), 's' (step) and '?' (query halt reason) commands.
921cb0ef41Sopenharmony_ci  void SetStopReply(Packet* pkt_out) const;
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci  enum class Status { Running, WaitingForSuspension, Suspended, Terminated };
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  void SetStatus(Status status, int8_t signal = 0,
971cb0ef41Sopenharmony_ci                 std::vector<wasm_addr_t> call_frames_ = {},
981cb0ef41Sopenharmony_ci                 Isolate* isolate = nullptr);
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  GdbServer* gdb_server_;
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  std::atomic<Status> status_;
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  // Signal being processed.
1051cb0ef41Sopenharmony_ci  std::atomic<int8_t> cur_signal_;
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  // Session object not owned by the Target.
1081cb0ef41Sopenharmony_ci  Session* session_;
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  // Map used to make fast lookups when handling query packets.
1111cb0ef41Sopenharmony_ci  typedef std::map<std::string, std::string> QueryPropertyMap;
1121cb0ef41Sopenharmony_ci  QueryPropertyMap query_properties_;
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  bool debugger_initial_suspension_;
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci  // Used to block waiting for suspension
1171cb0ef41Sopenharmony_ci  v8::base::Semaphore semaphore_;
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  mutable v8::base::Mutex mutex_;
1201cb0ef41Sopenharmony_ci  //////////////////////////////////////////////////////////////////////////////
1211cb0ef41Sopenharmony_ci  // Protected by {mutex_}:
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  // Current isolate. This is not null only when the target is in a Suspended
1241cb0ef41Sopenharmony_ci  // state and it is the isolate associated to the current call stack and used
1251cb0ef41Sopenharmony_ci  // for all debugging activities.
1261cb0ef41Sopenharmony_ci  Isolate* current_isolate_;
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  // Call stack when the execution is suspended.
1291cb0ef41Sopenharmony_ci  std::vector<wasm_addr_t> call_frames_;
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  // End of fields protected by {mutex_}.
1321cb0ef41Sopenharmony_ci  //////////////////////////////////////////////////////////////////////////////
1331cb0ef41Sopenharmony_ci};
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci}  // namespace gdb_server
1361cb0ef41Sopenharmony_ci}  // namespace wasm
1371cb0ef41Sopenharmony_ci}  // namespace internal
1381cb0ef41Sopenharmony_ci}  // namespace v8
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci#endif  // V8_DEBUG_WASM_GDB_SERVER_TARGET_H_
141