1353952Sdim//===-- GDBRemote.h ----------------------------------------------*- C++-*-===//
2353952Sdim//
3353952Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353952Sdim// See https://llvm.org/LICENSE.txt for license information.
5353952Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6353952Sdim//
7353952Sdim//===----------------------------------------------------------------------===//
8353952Sdim
9353952Sdim#ifndef liblldb_GDBRemote_h_
10353952Sdim#define liblldb_GDBRemote_h_
11353952Sdim
12357095Sdim#include "lldb/Utility/FileSpec.h"
13357095Sdim#include "lldb/Utility/Reproducer.h"
14353952Sdim#include "lldb/Utility/StreamString.h"
15353952Sdim#include "lldb/lldb-enumerations.h"
16353952Sdim#include "lldb/lldb-public.h"
17353952Sdim#include "llvm/Support/YAMLTraits.h"
18353952Sdim#include "llvm/Support/raw_ostream.h"
19353952Sdim
20353952Sdim#include <stddef.h>
21353952Sdim#include <stdint.h>
22353952Sdim#include <string>
23353952Sdim#include <vector>
24353952Sdim
25353952Sdimnamespace lldb_private {
26353952Sdim
27353952Sdimclass StreamGDBRemote : public StreamString {
28353952Sdimpublic:
29353952Sdim  StreamGDBRemote();
30353952Sdim
31353952Sdim  StreamGDBRemote(uint32_t flags, uint32_t addr_size,
32353952Sdim                  lldb::ByteOrder byte_order);
33353952Sdim
34353952Sdim  ~StreamGDBRemote() override;
35353952Sdim
36353952Sdim  /// Output a block of data to the stream performing GDB-remote escaping.
37353952Sdim  ///
38353952Sdim  /// \param[in] s
39353952Sdim  ///     A block of data.
40353952Sdim  ///
41353952Sdim  /// \param[in] src_len
42353952Sdim  ///     The amount of data to write.
43353952Sdim  ///
44353952Sdim  /// \return
45353952Sdim  ///     Number of bytes written.
46353952Sdim  // TODO: Convert this function to take ArrayRef<uint8_t>
47353952Sdim  int PutEscapedBytes(const void *s, size_t src_len);
48353952Sdim};
49353952Sdim
50353952Sdim/// GDB remote packet as used by the reproducer and the GDB remote
51353952Sdim/// communication history. Packets can be serialized to file.
52353952Sdimstruct GDBRemotePacket {
53353952Sdim
54353952Sdim  friend llvm::yaml::MappingTraits<GDBRemotePacket>;
55353952Sdim
56353952Sdim  enum Type { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv };
57353952Sdim
58353952Sdim  GDBRemotePacket()
59353952Sdim      : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), packet_idx(0),
60353952Sdim        tid(LLDB_INVALID_THREAD_ID) {}
61353952Sdim
62353952Sdim  void Clear() {
63353952Sdim    packet.data.clear();
64353952Sdim    type = ePacketTypeInvalid;
65353952Sdim    bytes_transmitted = 0;
66353952Sdim    packet_idx = 0;
67353952Sdim    tid = LLDB_INVALID_THREAD_ID;
68353952Sdim  }
69353952Sdim
70353952Sdim  struct BinaryData {
71353952Sdim    std::string data;
72353952Sdim  };
73353952Sdim
74353952Sdim  void Dump(Stream &strm) const;
75353952Sdim
76353952Sdim  BinaryData packet;
77353952Sdim  Type type;
78353952Sdim  uint32_t bytes_transmitted;
79353952Sdim  uint32_t packet_idx;
80353952Sdim  lldb::tid_t tid;
81353952Sdim
82353952Sdimprivate:
83353952Sdim  llvm::StringRef GetTypeStr() const;
84353952Sdim};
85353952Sdim
86357095Sdimnamespace repro {
87357095Sdimclass PacketRecorder : public AbstractRecorder {
88357095Sdimpublic:
89357095Sdim  PacketRecorder(const FileSpec &filename, std::error_code &ec)
90357095Sdim      : AbstractRecorder(filename, ec) {}
91357095Sdim
92357095Sdim  static llvm::Expected<std::unique_ptr<PacketRecorder>>
93357095Sdim  Create(const FileSpec &filename);
94357095Sdim
95357095Sdim  void Record(const GDBRemotePacket &packet);
96357095Sdim};
97357095Sdim
98357095Sdimclass GDBRemoteProvider : public repro::Provider<GDBRemoteProvider> {
99357095Sdimpublic:
100357095Sdim  struct Info {
101357095Sdim    static const char *name;
102357095Sdim    static const char *file;
103357095Sdim  };
104357095Sdim
105357095Sdim  GDBRemoteProvider(const FileSpec &directory) : Provider(directory) {}
106357095Sdim
107357095Sdim  llvm::raw_ostream *GetHistoryStream();
108357095Sdim  PacketRecorder *GetNewPacketRecorder();
109357095Sdim
110357095Sdim  void SetCallback(std::function<void()> callback) {
111357095Sdim    m_callback = std::move(callback);
112357095Sdim  }
113357095Sdim
114357095Sdim  void Keep() override;
115357095Sdim  void Discard() override;
116357095Sdim
117357095Sdim  static char ID;
118357095Sdim
119357095Sdimprivate:
120357095Sdim  std::function<void()> m_callback;
121357095Sdim  std::unique_ptr<llvm::raw_fd_ostream> m_stream_up;
122357095Sdim  std::vector<std::unique_ptr<PacketRecorder>> m_packet_recorders;
123357095Sdim};
124357095Sdim
125357095Sdim} // namespace repro
126353952Sdim} // namespace lldb_private
127353952Sdim
128353952SdimLLVM_YAML_IS_DOCUMENT_LIST_VECTOR(lldb_private::GDBRemotePacket)
129353952SdimLLVM_YAML_IS_DOCUMENT_LIST_VECTOR(std::vector<lldb_private::GDBRemotePacket>)
130353952Sdim
131353952Sdimnamespace llvm {
132353952Sdimnamespace yaml {
133353952Sdim
134353952Sdimtemplate <>
135353952Sdimstruct ScalarEnumerationTraits<lldb_private::GDBRemotePacket::Type> {
136353952Sdim  static void enumeration(IO &io, lldb_private::GDBRemotePacket::Type &value);
137353952Sdim};
138353952Sdim
139353952Sdimtemplate <> struct ScalarTraits<lldb_private::GDBRemotePacket::BinaryData> {
140353952Sdim  static void output(const lldb_private::GDBRemotePacket::BinaryData &, void *,
141353952Sdim                     raw_ostream &);
142353952Sdim
143353952Sdim  static StringRef input(StringRef, void *,
144353952Sdim                         lldb_private::GDBRemotePacket::BinaryData &);
145353952Sdim
146353952Sdim  static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
147353952Sdim};
148353952Sdim
149353952Sdimtemplate <> struct MappingTraits<lldb_private::GDBRemotePacket> {
150353952Sdim  static void mapping(IO &io, lldb_private::GDBRemotePacket &Packet);
151353952Sdim
152353952Sdim  static StringRef validate(IO &io, lldb_private::GDBRemotePacket &);
153353952Sdim};
154353952Sdim
155353952Sdim} // namespace yaml
156353952Sdim} // namespace llvm
157353952Sdim
158353952Sdim#endif // liblldb_GDBRemote_h_
159