Skip to content

Commit ff5225b

Browse files
committed
[Reproducer] Move GDB Remote Packet into Utility. (NFC)
To support dumping the reproducer's GDB remote packets, we need the (de)serialization logic to live in Utility rather than the GDB remote plugin. This patch renames StreamGDBRemote to GDBRemote and moves the relevant packet code there. Its uses in the GDBRemoteCommunicationHistory and the GDBRemoteCommunicationReplayServer are updated as well. Differential revision: https://reviews.llvm.org/D67523 llvm-svn: 371907
1 parent ae530c5 commit ff5225b

17 files changed

+237
-246
lines changed

lldb/include/lldb/Utility/GDBRemote.h

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//===-- GDBRemote.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_GDBRemote_h_
10+
#define liblldb_GDBRemote_h_
11+
12+
#include "lldb/Utility/StreamString.h"
13+
#include "lldb/lldb-enumerations.h"
14+
#include "lldb/lldb-public.h"
15+
#include "llvm/Support/YAMLTraits.h"
16+
#include "llvm/Support/raw_ostream.h"
17+
18+
#include <stddef.h>
19+
#include <stdint.h>
20+
#include <string>
21+
#include <vector>
22+
23+
namespace lldb_private {
24+
25+
class StreamGDBRemote : public StreamString {
26+
public:
27+
StreamGDBRemote();
28+
29+
StreamGDBRemote(uint32_t flags, uint32_t addr_size,
30+
lldb::ByteOrder byte_order);
31+
32+
~StreamGDBRemote() override;
33+
34+
/// Output a block of data to the stream performing GDB-remote escaping.
35+
///
36+
/// \param[in] s
37+
/// A block of data.
38+
///
39+
/// \param[in] src_len
40+
/// The amount of data to write.
41+
///
42+
/// \return
43+
/// Number of bytes written.
44+
// TODO: Convert this function to take ArrayRef<uint8_t>
45+
int PutEscapedBytes(const void *s, size_t src_len);
46+
};
47+
48+
/// GDB remote packet as used by the reproducer and the GDB remote
49+
/// communication history. Packets can be serialized to file.
50+
struct GDBRemotePacket {
51+
52+
friend llvm::yaml::MappingTraits<GDBRemotePacket>;
53+
54+
enum Type { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv };
55+
56+
GDBRemotePacket()
57+
: packet(), type(ePacketTypeInvalid), bytes_transmitted(0), packet_idx(0),
58+
tid(LLDB_INVALID_THREAD_ID) {}
59+
60+
void Clear() {
61+
packet.data.clear();
62+
type = ePacketTypeInvalid;
63+
bytes_transmitted = 0;
64+
packet_idx = 0;
65+
tid = LLDB_INVALID_THREAD_ID;
66+
}
67+
68+
struct BinaryData {
69+
std::string data;
70+
};
71+
72+
void Serialize(llvm::raw_ostream &strm) const;
73+
74+
BinaryData packet;
75+
Type type;
76+
uint32_t bytes_transmitted;
77+
uint32_t packet_idx;
78+
lldb::tid_t tid;
79+
};
80+
81+
} // namespace lldb_private
82+
83+
LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(lldb_private::GDBRemotePacket)
84+
LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(std::vector<lldb_private::GDBRemotePacket>)
85+
86+
namespace llvm {
87+
namespace yaml {
88+
89+
template <>
90+
struct ScalarEnumerationTraits<lldb_private::GDBRemotePacket::Type> {
91+
static void enumeration(IO &io, lldb_private::GDBRemotePacket::Type &value);
92+
};
93+
94+
template <> struct ScalarTraits<lldb_private::GDBRemotePacket::BinaryData> {
95+
static void output(const lldb_private::GDBRemotePacket::BinaryData &, void *,
96+
raw_ostream &);
97+
98+
static StringRef input(StringRef, void *,
99+
lldb_private::GDBRemotePacket::BinaryData &);
100+
101+
static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
102+
};
103+
104+
template <> struct MappingTraits<lldb_private::GDBRemotePacket> {
105+
static void mapping(IO &io, lldb_private::GDBRemotePacket &Packet);
106+
107+
static StringRef validate(IO &io, lldb_private::GDBRemotePacket &);
108+
};
109+
110+
} // namespace yaml
111+
} // namespace llvm
112+
113+
#endif // liblldb_GDBRemote_h_

lldb/include/lldb/Utility/Reproducer.h

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#define LLDB_UTILITY_REPRODUCER_H
1111

1212
#include "lldb/Utility/FileSpec.h"
13-
1413
#include "llvm/ADT/DenseMap.h"
1514
#include "llvm/Support/Error.h"
1615
#include "llvm/Support/FileCollector.h"

lldb/include/lldb/Utility/StreamGDBRemote.h

-45
This file was deleted.

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp

+4-8
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ size_t GDBRemoteCommunication::SendAck() {
103103
char ch = '+';
104104
const size_t bytes_written = Write(&ch, 1, status, nullptr);
105105
LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
106-
m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
107-
bytes_written);
106+
m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written);
108107
return bytes_written;
109108
}
110109

@@ -114,8 +113,7 @@ size_t GDBRemoteCommunication::SendNack() {
114113
char ch = '-';
115114
const size_t bytes_written = Write(&ch, 1, status, nullptr);
116115
LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
117-
m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
118-
bytes_written);
116+
m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written);
119117
return bytes_written;
120118
}
121119

@@ -178,8 +176,7 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
178176
}
179177

180178
m_history.AddPacket(packet.str(), packet_length,
181-
GDBRemoteCommunicationHistory::ePacketTypeSend,
182-
bytes_written);
179+
GDBRemotePacket::ePacketTypeSend, bytes_written);
183180

184181
if (bytes_written == packet_length) {
185182
if (!skip_ack && GetSendAcks())
@@ -809,8 +806,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
809806
}
810807

811808
m_history.AddPacket(m_bytes, total_length,
812-
GDBRemoteCommunicationHistory::ePacketTypeRecv,
813-
total_length);
809+
GDBRemotePacket::ePacketTypeRecv, total_length);
814810

815811
// Copy the packet from m_bytes to packet_str expanding the run-length
816812
// encoding in the process. Reserve enough byte for the most common case

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include <vector>
1919

2020
#include "lldb/Utility/ArchSpec.h"
21-
#include "lldb/Utility/StreamGDBRemote.h"
21+
#include "lldb/Utility/GDBRemote.h"
2222
#include "lldb/Utility/StructuredData.h"
2323
#if defined(_WIN32)
2424
#include "lldb/Host/windows/PosixApi.h"

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp

+14-52
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ using namespace lldb;
1818
using namespace lldb_private;
1919
using namespace lldb_private::process_gdb_remote;
2020

21-
void GDBRemoteCommunicationHistory::Entry::Serialize(raw_ostream &strm) const {
22-
yaml::Output yout(strm);
23-
yout << const_cast<GDBRemoteCommunicationHistory::Entry &>(*this);
24-
strm.flush();
25-
}
26-
2721
GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
2822
: m_packets(), m_curr_idx(0), m_total_packet_count(0),
2923
m_dumped_to_log(false) {
@@ -33,7 +27,8 @@ GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
3327

3428
GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {}
3529

36-
void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
30+
void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
31+
GDBRemotePacket::Type type,
3732
uint32_t bytes_transmitted) {
3833
const size_t size = m_packets.size();
3934
if (size == 0)
@@ -50,7 +45,8 @@ void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
5045
}
5146

5247
void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
53-
uint32_t src_len, PacketType type,
48+
uint32_t src_len,
49+
GDBRemotePacket::Type type,
5450
uint32_t bytes_transmitted) {
5551
const size_t size = m_packets.size();
5652
if (size == 0)
@@ -72,12 +68,14 @@ void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
7268
const uint32_t stop_idx = m_curr_idx + size;
7369
for (uint32_t i = first_idx; i < stop_idx; ++i) {
7470
const uint32_t idx = NormalizeIndex(i);
75-
const Entry &entry = m_packets[idx];
76-
if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
71+
const GDBRemotePacket &entry = m_packets[idx];
72+
if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
73+
entry.packet.data.empty())
7774
break;
7875
strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
7976
entry.packet_idx, entry.tid, entry.bytes_transmitted,
80-
(entry.type == ePacketTypeSend) ? "send" : "read",
77+
(entry.type == GDBRemotePacket::ePacketTypeSend) ? "send"
78+
: "read",
8179
entry.packet.data.c_str());
8280
}
8381
}
@@ -92,51 +90,15 @@ void GDBRemoteCommunicationHistory::Dump(Log *log) const {
9290
const uint32_t stop_idx = m_curr_idx + size;
9391
for (uint32_t i = first_idx; i < stop_idx; ++i) {
9492
const uint32_t idx = NormalizeIndex(i);
95-
const Entry &entry = m_packets[idx];
96-
if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
93+
const GDBRemotePacket &entry = m_packets[idx];
94+
if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
95+
entry.packet.data.empty())
9796
break;
9897
LLDB_LOGF(log, "history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
9998
entry.packet_idx, entry.tid, entry.bytes_transmitted,
100-
(entry.type == ePacketTypeSend) ? "send" : "read",
99+
(entry.type == GDBRemotePacket::ePacketTypeSend) ? "send"
100+
: "read",
101101
entry.packet.data.c_str());
102102
}
103103
}
104104

105-
void yaml::ScalarEnumerationTraits<GDBRemoteCommunicationHistory::PacketType>::
106-
enumeration(IO &io, GDBRemoteCommunicationHistory::PacketType &value) {
107-
io.enumCase(value, "Invalid",
108-
GDBRemoteCommunicationHistory::ePacketTypeInvalid);
109-
io.enumCase(value, "Send", GDBRemoteCommunicationHistory::ePacketTypeSend);
110-
io.enumCase(value, "Recv", GDBRemoteCommunicationHistory::ePacketTypeRecv);
111-
}
112-
113-
void yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::
114-
output(const GDBRemoteCommunicationHistory::Entry::BinaryData &Val, void *,
115-
raw_ostream &Out) {
116-
Out << toHex(Val.data);
117-
}
118-
119-
StringRef
120-
yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::input(
121-
StringRef Scalar, void *,
122-
GDBRemoteCommunicationHistory::Entry::BinaryData &Val) {
123-
Val.data = fromHex(Scalar);
124-
return {};
125-
}
126-
127-
void yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::mapping(
128-
IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
129-
io.mapRequired("packet", Entry.packet);
130-
io.mapRequired("type", Entry.type);
131-
io.mapRequired("bytes", Entry.bytes_transmitted);
132-
io.mapRequired("index", Entry.packet_idx);
133-
io.mapRequired("tid", Entry.tid);
134-
}
135-
136-
StringRef yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::validate(
137-
IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
138-
if (Entry.bytes_transmitted != Entry.packet.data.size())
139-
return "BinaryData size doesn't match bytes transmitted";
140-
141-
return {};
142-
}

0 commit comments

Comments
 (0)