blob: d0ca6a0235c9b256e023842ceb1a2bc845ca447a [file] [log] [blame]
Jonas Devlieghere9e046f02018-11-13 19:18:16 +00001//===-- GDBRemoteCommunicationHistory.h--------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_GDBRemoteCommunicationHistory_h_
11#define liblldb_GDBRemoteCommunicationHistory_h_
12
13#include <string>
14#include <vector>
15
16#include "lldb/lldb-public.h"
17#include "llvm/Support/YAMLTraits.h"
18#include "llvm/Support/raw_ostream.h"
19
20namespace lldb_private {
21namespace process_gdb_remote {
22
23/// The history keeps a circular buffer of GDB remote packets. The history is
24/// used for logging and replaying GDB remote packets.
25class GDBRemoteCommunicationHistory {
26public:
27 friend llvm::yaml::MappingTraits<GDBRemoteCommunicationHistory>;
28
29 enum PacketType { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv };
30
31 /// Entry in the ring buffer containing the packet data, its type, size and
32 /// index. Entries can be serialized to file.
33 struct Entry {
34 Entry()
35 : packet(), type(ePacketTypeInvalid), bytes_transmitted(0),
36 packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {}
37
38 void Clear() {
39 packet.data.clear();
40 type = ePacketTypeInvalid;
41 bytes_transmitted = 0;
42 packet_idx = 0;
43 tid = LLDB_INVALID_THREAD_ID;
44 }
45
46 struct BinaryData {
47 std::string data;
48 };
49
50 void Serialize(llvm::raw_ostream &strm) const;
51
52 BinaryData packet;
53 PacketType type;
54 uint32_t bytes_transmitted;
55 uint32_t packet_idx;
56 lldb::tid_t tid;
57 };
58
59 GDBRemoteCommunicationHistory(uint32_t size = 0);
60
61 ~GDBRemoteCommunicationHistory();
62
63 // For single char packets for ack, nack and /x03
64 void AddPacket(char packet_char, PacketType type, uint32_t bytes_transmitted);
65
66 void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
67 uint32_t bytes_transmitted);
68
69 void Dump(Stream &strm) const;
70 void Dump(Log *log) const;
71 bool DidDumpToLog() const { return m_dumped_to_log; }
72
73 void SetStream(llvm::raw_ostream *strm) { m_stream = strm; }
74
75private:
76 uint32_t GetFirstSavedPacketIndex() const {
77 if (m_total_packet_count < m_packets.size())
78 return 0;
79 else
80 return m_curr_idx + 1;
81 }
82
83 uint32_t GetNumPacketsInHistory() const {
84 if (m_total_packet_count < m_packets.size())
85 return m_total_packet_count;
86 else
87 return (uint32_t)m_packets.size();
88 }
89
90 uint32_t GetNextIndex() {
91 ++m_total_packet_count;
92 const uint32_t idx = m_curr_idx;
93 m_curr_idx = NormalizeIndex(idx + 1);
94 return idx;
95 }
96
97 uint32_t NormalizeIndex(uint32_t i) const {
98 return m_packets.empty() ? 0 : i % m_packets.size();
99 }
100
101 std::vector<Entry> m_packets;
102 uint32_t m_curr_idx;
103 uint32_t m_total_packet_count;
104 mutable bool m_dumped_to_log;
105 llvm::raw_ostream *m_stream = nullptr;
106};
107
108} // namespace process_gdb_remote
109} // namespace lldb_private
110
111LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
112 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry)
113
114namespace llvm {
115namespace yaml {
116
117template <>
118struct ScalarEnumerationTraits<lldb_private::process_gdb_remote::
119 GDBRemoteCommunicationHistory::PacketType> {
120 static void enumeration(IO &io,
121 lldb_private::process_gdb_remote::
122 GDBRemoteCommunicationHistory::PacketType &value);
123};
124
125template <>
126struct ScalarTraits<lldb_private::process_gdb_remote::
127 GDBRemoteCommunicationHistory::Entry::BinaryData> {
128 static void output(const lldb_private::process_gdb_remote::
129 GDBRemoteCommunicationHistory::Entry::BinaryData &,
130 void *, raw_ostream &);
131
132 static StringRef
133 input(StringRef, void *,
134 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry::
135 BinaryData &);
136
137 static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
138};
139
140template <>
141struct MappingTraits<
142 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry> {
143 static void
144 mapping(IO &io,
145 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry
146 &Entry);
147
148 static StringRef validate(
149 IO &io,
150 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry &);
151};
152
153} // namespace yaml
154} // namespace llvm
155
156#endif // liblldb_GDBRemoteCommunicationHistory_h_