1 //===-- 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 20 namespace lldb_private { 21 namespace 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. 25 class GDBRemoteCommunicationHistory { 26 public: 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 75 private: 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 111 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR( 112 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry) 113 114 namespace llvm { 115 namespace yaml { 116 117 template <> 118 struct 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 125 template <> 126 struct 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 140 template <> 141 struct 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_ 157