v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
session.cc
Go to the documentation of this file.
1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
8
9namespace v8 {
10namespace internal {
11namespace wasm {
12namespace gdb_server {
13
15 : io_(transport), connected_(true), ack_enabled_(true) {}
16
18
20
21bool Session::IsDataAvailable() const { return io_->IsDataAvailable(); }
22
23bool Session::IsConnected() const { return connected_; }
24
26 io_->Disconnect();
27 connected_ = false;
28}
29
30bool Session::GetChar(char* ch) {
31 if (!io_->Read(ch, 1)) {
32 Disconnect();
33 return false;
34 }
35
36 return true;
37}
38
39bool Session::SendPacket(Packet* pkt, bool expect_ack) {
40 char ch;
41 do {
42 std::string data = pkt->GetPacketData();
43
44 TRACE_GDB_REMOTE("TX %s\n", data.size() < 160
45 ? data.c_str()
46 : (data.substr(0, 160) + "...").c_str());
47 if (!io_->Write(data.data(), static_cast<int32_t>(data.length()))) {
48 return false;
49 }
50
51 // If ACKs are off, we are done.
52 if (!expect_ack || !ack_enabled_) {
53 break;
54 }
55
56 // Otherwise, poll for '+'
57 if (!GetChar(&ch)) {
58 return false;
59 }
60
61 // Retry if we didn't get a '+'
62 } while (ch != '+');
63
64 return true;
65}
66
67bool Session::GetPayload(Packet* pkt, uint8_t* checksum) {
68 pkt->Clear();
69 *checksum = 0;
70
71 // Stream in the characters
72 char ch;
73 while (GetChar(&ch)) {
74 if (ch == '#') {
75 // If we see a '#' we must be done with the data.
76 return true;
77 } else if (ch == '$') {
78 // If we see a '$' we must have missed the last cmd, let's retry.
79 TRACE_GDB_REMOTE("RX Missing $, retry.\n");
80 *checksum = 0;
81 pkt->Clear();
82 } else {
83 // Keep a running XSUM.
84 *checksum += ch;
85 pkt->AddRawChar(ch);
86 }
87 }
88 return false;
89}
90
92 while (true) {
93 // Toss characters until we see a start of command
94 char ch;
95 do {
96 if (!GetChar(&ch)) {
97 return false;
98 }
99 } while (ch != '$');
100
101 uint8_t running_checksum = 0;
102 if (!GetPayload(pkt, &running_checksum)) {
103 return false;
104 }
105
106 // Get two nibble checksum
107 uint8_t trailing_checksum = 0;
108 char chars[2];
109 if (!GetChar(&chars[0]) || !GetChar(&chars[1]) ||
110 !HexToUInt8(chars, &trailing_checksum)) {
111 return false;
112 }
113
114 TRACE_GDB_REMOTE("RX $%s#%c%c\n", pkt->GetPayload(), chars[0], chars[1]);
115
116 pkt->ParseSequence();
117
118 // If ACKs are off, we are done.
119 if (!ack_enabled_) {
120 return true;
121 }
122
123 // If the XSUMs don't match, signal bad packet
124 if (trailing_checksum == running_checksum) {
125 char out[3] = {'+', 0, 0};
126
127 // If we have a sequence number
128 int32_t seq;
129 if (pkt->GetSequence(&seq)) {
130 // Respond with sequence number
131 UInt8ToHex(seq, &out[1]);
132 return io_->Write(out, 3);
133 } else {
134 return io_->Write(out, 1);
135 }
136 } else {
137 // Resend a bad XSUM and look for retransmit
138 TRACE_GDB_REMOTE("RX Bad XSUM, retry\n");
139 io_->Write("-", 1);
140 // retry...
141 }
142 }
143}
144
145} // namespace gdb_server
146} // namespace wasm
147} // namespace internal
148} // namespace v8
const char * GetPayload() const
Definition packet.cc:284
std::string GetPacketData() const
Definition packet.cc:321
bool GetSequence(int32_t *seq) const
Definition packet.cc:288
bool SendPacket(Packet *packet, bool expect_ack=true)
Definition session.cc:39
Session(TransportBase *transport)
Definition session.cc:14
bool GetPayload(Packet *pkt, uint8_t *checksum)
Definition session.cc:67
virtual bool Write(const char *src, int32_t len)=0
virtual bool Read(char *dst, int32_t len)=0
#define TRACE_GDB_REMOTE(...)
void UInt8ToHex(uint8_t byte, char chars[2])
bool HexToUInt8(const char chars[2], uint8_t *byte)
Definition c-api.cc:87