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