]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / gdb-remote / GDBRemoteCommunicationHistory.cpp
1 //===-- GDBRemoteCommunicationHistory.cpp -----------------------*- 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 #include "GDBRemoteCommunicationHistory.h"
11
12 // Other libraries and framework includes
13 #include "lldb/Core/StreamFile.h"
14 #include "lldb/Utility/ConstString.h"
15 #include "lldb/Utility/Log.h"
16
17 using namespace llvm;
18 using namespace lldb;
19 using namespace lldb_private;
20 using namespace lldb_private::process_gdb_remote;
21
22 void GDBRemoteCommunicationHistory::Entry::Serialize(raw_ostream &strm) const {
23   yaml::Output yout(strm);
24   yout << const_cast<GDBRemoteCommunicationHistory::Entry &>(*this);
25   strm.flush();
26 }
27
28 GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
29     : m_packets(), m_curr_idx(0), m_total_packet_count(0),
30       m_dumped_to_log(false) {
31   if (size)
32     m_packets.resize(size);
33 }
34
35 GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {}
36
37 void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
38                                               uint32_t bytes_transmitted) {
39   const size_t size = m_packets.size();
40   if (size == 0)
41     return;
42
43   const uint32_t idx = GetNextIndex();
44   m_packets[idx].packet.data.assign(1, packet_char);
45   m_packets[idx].type = type;
46   m_packets[idx].bytes_transmitted = bytes_transmitted;
47   m_packets[idx].packet_idx = m_total_packet_count;
48   m_packets[idx].tid = llvm::get_threadid();
49   if (m_stream && type == ePacketTypeRecv)
50     m_packets[idx].Serialize(*m_stream);
51 }
52
53 void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
54                                               uint32_t src_len, PacketType type,
55                                               uint32_t bytes_transmitted) {
56   const size_t size = m_packets.size();
57   if (size == 0)
58     return;
59
60   const uint32_t idx = GetNextIndex();
61   m_packets[idx].packet.data.assign(src, 0, src_len);
62   m_packets[idx].type = type;
63   m_packets[idx].bytes_transmitted = bytes_transmitted;
64   m_packets[idx].packet_idx = m_total_packet_count;
65   m_packets[idx].tid = llvm::get_threadid();
66   if (m_stream && type == ePacketTypeRecv)
67     m_packets[idx].Serialize(*m_stream);
68 }
69
70 void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
71   const uint32_t size = GetNumPacketsInHistory();
72   const uint32_t first_idx = GetFirstSavedPacketIndex();
73   const uint32_t stop_idx = m_curr_idx + size;
74   for (uint32_t i = first_idx; i < stop_idx; ++i) {
75     const uint32_t idx = NormalizeIndex(i);
76     const Entry &entry = m_packets[idx];
77     if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
78       break;
79     strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
80                 entry.packet_idx, entry.tid, entry.bytes_transmitted,
81                 (entry.type == ePacketTypeSend) ? "send" : "read",
82                 entry.packet.data.c_str());
83   }
84 }
85
86 void GDBRemoteCommunicationHistory::Dump(Log *log) const {
87   if (!log || m_dumped_to_log)
88     return;
89
90   m_dumped_to_log = true;
91   const uint32_t size = GetNumPacketsInHistory();
92   const uint32_t first_idx = GetFirstSavedPacketIndex();
93   const uint32_t stop_idx = m_curr_idx + size;
94   for (uint32_t i = first_idx; i < stop_idx; ++i) {
95     const uint32_t idx = NormalizeIndex(i);
96     const Entry &entry = m_packets[idx];
97     if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
98       break;
99     log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
100                 entry.packet_idx, entry.tid, entry.bytes_transmitted,
101                 (entry.type == ePacketTypeSend) ? "send" : "read",
102                 entry.packet.data.c_str());
103   }
104 }
105
106 void yaml::ScalarEnumerationTraits<GDBRemoteCommunicationHistory::PacketType>::
107     enumeration(IO &io, GDBRemoteCommunicationHistory::PacketType &value) {
108   io.enumCase(value, "Invalid",
109               GDBRemoteCommunicationHistory::ePacketTypeInvalid);
110   io.enumCase(value, "Send", GDBRemoteCommunicationHistory::ePacketTypeSend);
111   io.enumCase(value, "Recv", GDBRemoteCommunicationHistory::ePacketTypeRecv);
112 }
113
114 void yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::
115     output(const GDBRemoteCommunicationHistory::Entry::BinaryData &Val, void *,
116            raw_ostream &Out) {
117   Out << toHex(Val.data);
118 }
119
120 StringRef
121 yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::input(
122     StringRef Scalar, void *,
123     GDBRemoteCommunicationHistory::Entry::BinaryData &Val) {
124   Val.data = fromHex(Scalar);
125   return {};
126 }
127
128 void yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::mapping(
129     IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
130   io.mapRequired("packet", Entry.packet);
131   io.mapRequired("type", Entry.type);
132   io.mapRequired("bytes", Entry.bytes_transmitted);
133   io.mapRequired("index", Entry.packet_idx);
134   io.mapRequired("tid", Entry.tid);
135 }
136
137 StringRef yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::validate(
138     IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
139   if (Entry.bytes_transmitted != Entry.packet.data.size())
140     return "BinaryData size doesn't match bytes transmitted";
141
142   return {};
143 }