1 //===-- GDBRemoteCommunicationClient.cpp ----------------------------------===//
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 #include "GDBRemoteCommunicationClient.h"
10
11 #include <cmath>
12 #include <sys/stat.h>
13
14 #include <numeric>
15 #include <sstream>
16
17 #include "lldb/Core/ModuleSpec.h"
18 #include "lldb/Host/HostInfo.h"
19 #include "lldb/Host/StringConvert.h"
20 #include "lldb/Host/XML.h"
21 #include "lldb/Symbol/Symbol.h"
22 #include "lldb/Target/MemoryRegionInfo.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/UnixSignals.h"
25 #include "lldb/Utility/Args.h"
26 #include "lldb/Utility/DataBufferHeap.h"
27 #include "lldb/Utility/LLDBAssert.h"
28 #include "lldb/Utility/Log.h"
29 #include "lldb/Utility/State.h"
30 #include "lldb/Utility/StreamString.h"
31
32 #include "ProcessGDBRemote.h"
33 #include "ProcessGDBRemoteLog.h"
34 #include "lldb/Host/Config.h"
35 #include "lldb/Utility/StringExtractorGDBRemote.h"
36
37 #include "llvm/ADT/StringSwitch.h"
38 #include "llvm/Support/JSON.h"
39
40 #if defined(HAVE_LIBCOMPRESSION)
41 #include <compression.h>
42 #endif
43
44 using namespace lldb;
45 using namespace lldb_private::process_gdb_remote;
46 using namespace lldb_private;
47 using namespace std::chrono;
48
operator <<(llvm::raw_ostream & os,const QOffsets & offsets)49 llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os,
50 const QOffsets &offsets) {
51 return os << llvm::formatv(
52 "QOffsets({0}, [{1:@[x]}])", offsets.segments,
53 llvm::make_range(offsets.offsets.begin(), offsets.offsets.end()));
54 }
55
56 // GDBRemoteCommunicationClient constructor
GDBRemoteCommunicationClient()57 GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
58 : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
59
60 m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
61 m_supports_qUserName(true), m_supports_qGroupName(true),
62 m_supports_qThreadStopInfo(true), m_supports_z0(true),
63 m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
64 m_supports_z4(true), m_supports_QEnvironment(true),
65 m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
66 m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
67 m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
68
69 m_host_arch(), m_process_arch(), m_os_build(), m_os_kernel(),
70 m_hostname(), m_gdb_server_name(), m_default_packet_timeout(0),
71 m_qSupported_response(), m_supported_async_json_packets_sp(),
72 m_qXfer_memory_map() {}
73
74 // Destructor
~GDBRemoteCommunicationClient()75 GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
76 if (IsConnected())
77 Disconnect();
78 }
79
HandshakeWithServer(Status * error_ptr)80 bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
81 ResetDiscoverableSettings(false);
82
83 // Start the read thread after we send the handshake ack since if we fail to
84 // send the handshake ack, there is no reason to continue...
85 if (SendAck()) {
86 // Wait for any responses that might have been queued up in the remote
87 // GDB server and flush them all
88 StringExtractorGDBRemote response;
89 PacketResult packet_result = PacketResult::Success;
90 while (packet_result == PacketResult::Success)
91 packet_result = ReadPacket(response, milliseconds(10), false);
92
93 // The return value from QueryNoAckModeSupported() is true if the packet
94 // was sent and _any_ response (including UNIMPLEMENTED) was received), or
95 // false if no response was received. This quickly tells us if we have a
96 // live connection to a remote GDB server...
97 if (QueryNoAckModeSupported()) {
98 return true;
99 } else {
100 if (error_ptr)
101 error_ptr->SetErrorString("failed to get reply to handshake packet");
102 }
103 } else {
104 if (error_ptr)
105 error_ptr->SetErrorString("failed to send the handshake ack");
106 }
107 return false;
108 }
109
GetEchoSupported()110 bool GDBRemoteCommunicationClient::GetEchoSupported() {
111 if (m_supports_qEcho == eLazyBoolCalculate) {
112 GetRemoteQSupported();
113 }
114 return m_supports_qEcho == eLazyBoolYes;
115 }
116
GetQPassSignalsSupported()117 bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
118 if (m_supports_QPassSignals == eLazyBoolCalculate) {
119 GetRemoteQSupported();
120 }
121 return m_supports_QPassSignals == eLazyBoolYes;
122 }
123
GetAugmentedLibrariesSVR4ReadSupported()124 bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
125 if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
126 GetRemoteQSupported();
127 }
128 return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
129 }
130
GetQXferLibrariesSVR4ReadSupported()131 bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
132 if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
133 GetRemoteQSupported();
134 }
135 return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
136 }
137
GetQXferLibrariesReadSupported()138 bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
139 if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
140 GetRemoteQSupported();
141 }
142 return m_supports_qXfer_libraries_read == eLazyBoolYes;
143 }
144
GetQXferAuxvReadSupported()145 bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
146 if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
147 GetRemoteQSupported();
148 }
149 return m_supports_qXfer_auxv_read == eLazyBoolYes;
150 }
151
GetQXferFeaturesReadSupported()152 bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
153 if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
154 GetRemoteQSupported();
155 }
156 return m_supports_qXfer_features_read == eLazyBoolYes;
157 }
158
GetQXferMemoryMapReadSupported()159 bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
160 if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {
161 GetRemoteQSupported();
162 }
163 return m_supports_qXfer_memory_map_read == eLazyBoolYes;
164 }
165
GetRemoteMaxPacketSize()166 uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
167 if (m_max_packet_size == 0) {
168 GetRemoteQSupported();
169 }
170 return m_max_packet_size;
171 }
172
QueryNoAckModeSupported()173 bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
174 if (m_supports_not_sending_acks == eLazyBoolCalculate) {
175 m_send_acks = true;
176 m_supports_not_sending_acks = eLazyBoolNo;
177
178 // This is the first real packet that we'll send in a debug session and it
179 // may take a little longer than normal to receive a reply. Wait at least
180 // 6 seconds for a reply to this packet.
181
182 ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
183
184 StringExtractorGDBRemote response;
185 if (SendPacketAndWaitForResponse("QStartNoAckMode", response) ==
186 PacketResult::Success) {
187 if (response.IsOKResponse()) {
188 m_send_acks = false;
189 m_supports_not_sending_acks = eLazyBoolYes;
190 }
191 return true;
192 }
193 }
194 return false;
195 }
196
GetListThreadsInStopReplySupported()197 void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
198 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
199 m_supports_threads_in_stop_reply = eLazyBoolNo;
200
201 StringExtractorGDBRemote response;
202 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response) ==
203 PacketResult::Success) {
204 if (response.IsOKResponse())
205 m_supports_threads_in_stop_reply = eLazyBoolYes;
206 }
207 }
208 }
209
GetVAttachOrWaitSupported()210 bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
211 if (m_attach_or_wait_reply == eLazyBoolCalculate) {
212 m_attach_or_wait_reply = eLazyBoolNo;
213
214 StringExtractorGDBRemote response;
215 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response) ==
216 PacketResult::Success) {
217 if (response.IsOKResponse())
218 m_attach_or_wait_reply = eLazyBoolYes;
219 }
220 }
221 return m_attach_or_wait_reply == eLazyBoolYes;
222 }
223
GetSyncThreadStateSupported()224 bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
225 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
226 m_prepare_for_reg_writing_reply = eLazyBoolNo;
227
228 StringExtractorGDBRemote response;
229 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response) ==
230 PacketResult::Success) {
231 if (response.IsOKResponse())
232 m_prepare_for_reg_writing_reply = eLazyBoolYes;
233 }
234 }
235 return m_prepare_for_reg_writing_reply == eLazyBoolYes;
236 }
237
ResetDiscoverableSettings(bool did_exec)238 void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
239 if (!did_exec) {
240 // Hard reset everything, this is when we first connect to a GDB server
241 m_supports_not_sending_acks = eLazyBoolCalculate;
242 m_supports_thread_suffix = eLazyBoolCalculate;
243 m_supports_threads_in_stop_reply = eLazyBoolCalculate;
244 m_supports_vCont_c = eLazyBoolCalculate;
245 m_supports_vCont_C = eLazyBoolCalculate;
246 m_supports_vCont_s = eLazyBoolCalculate;
247 m_supports_vCont_S = eLazyBoolCalculate;
248 m_supports_p = eLazyBoolCalculate;
249 m_supports_x = eLazyBoolCalculate;
250 m_supports_QSaveRegisterState = eLazyBoolCalculate;
251 m_qHostInfo_is_valid = eLazyBoolCalculate;
252 m_curr_pid_is_valid = eLazyBoolCalculate;
253 m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
254 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
255 m_supports_memory_region_info = eLazyBoolCalculate;
256 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
257 m_attach_or_wait_reply = eLazyBoolCalculate;
258 m_avoid_g_packets = eLazyBoolCalculate;
259 m_supports_multiprocess = eLazyBoolCalculate;
260 m_supports_qXfer_auxv_read = eLazyBoolCalculate;
261 m_supports_qXfer_libraries_read = eLazyBoolCalculate;
262 m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
263 m_supports_qXfer_features_read = eLazyBoolCalculate;
264 m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
265 m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
266 m_supports_qProcessInfoPID = true;
267 m_supports_qfProcessInfo = true;
268 m_supports_qUserName = true;
269 m_supports_qGroupName = true;
270 m_supports_qThreadStopInfo = true;
271 m_supports_z0 = true;
272 m_supports_z1 = true;
273 m_supports_z2 = true;
274 m_supports_z3 = true;
275 m_supports_z4 = true;
276 m_supports_QEnvironment = true;
277 m_supports_QEnvironmentHexEncoded = true;
278 m_supports_qSymbol = true;
279 m_qSymbol_requests_done = false;
280 m_supports_qModuleInfo = true;
281 m_host_arch.Clear();
282 m_os_version = llvm::VersionTuple();
283 m_os_build.clear();
284 m_os_kernel.clear();
285 m_hostname.clear();
286 m_gdb_server_name.clear();
287 m_gdb_server_version = UINT32_MAX;
288 m_default_packet_timeout = seconds(0);
289 m_target_vm_page_size = 0;
290 m_max_packet_size = 0;
291 m_qSupported_response.clear();
292 m_supported_async_json_packets_is_valid = false;
293 m_supported_async_json_packets_sp.reset();
294 m_supports_jModulesInfo = true;
295 }
296
297 // These flags should be reset when we first connect to a GDB server and when
298 // our inferior process execs
299 m_qProcessInfo_is_valid = eLazyBoolCalculate;
300 m_process_arch.Clear();
301 }
302
GetRemoteQSupported()303 void GDBRemoteCommunicationClient::GetRemoteQSupported() {
304 // Clear out any capabilities we expect to see in the qSupported response
305 m_supports_qXfer_auxv_read = eLazyBoolNo;
306 m_supports_qXfer_libraries_read = eLazyBoolNo;
307 m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
308 m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
309 m_supports_qXfer_features_read = eLazyBoolNo;
310 m_supports_qXfer_memory_map_read = eLazyBoolNo;
311 m_supports_multiprocess = eLazyBoolNo;
312 m_supports_qEcho = eLazyBoolNo;
313 m_supports_QPassSignals = eLazyBoolNo;
314 m_supports_memory_tagging = eLazyBoolNo;
315
316 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
317 // not, we assume no limit
318
319 // build the qSupported packet
320 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc",
321 "multiprocess+"};
322 StreamString packet;
323 packet.PutCString("qSupported");
324 for (uint32_t i = 0; i < features.size(); ++i) {
325 packet.PutCString(i == 0 ? ":" : ";");
326 packet.PutCString(features[i]);
327 }
328
329 StringExtractorGDBRemote response;
330 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
331 PacketResult::Success) {
332 // Hang on to the qSupported packet, so that platforms can do custom
333 // configuration of the transport before attaching/launching the process.
334 m_qSupported_response = response.GetStringRef().str();
335
336 llvm::SmallVector<llvm::StringRef, 16> server_features;
337 response.GetStringRef().split(server_features, ';');
338
339 for (llvm::StringRef x : server_features) {
340 if (x == "qXfer:auxv:read+")
341 m_supports_qXfer_auxv_read = eLazyBoolYes;
342 else if (x == "qXfer:libraries-svr4:read+")
343 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
344 else if (x == "augmented-libraries-svr4-read") {
345 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
346 m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
347 } else if (x == "qXfer:libraries:read+")
348 m_supports_qXfer_libraries_read = eLazyBoolYes;
349 else if (x == "qXfer:features:read+")
350 m_supports_qXfer_features_read = eLazyBoolYes;
351 else if (x == "qXfer:memory-map:read+")
352 m_supports_qXfer_memory_map_read = eLazyBoolYes;
353 else if (x == "qEcho")
354 m_supports_qEcho = eLazyBoolYes;
355 else if (x == "QPassSignals+")
356 m_supports_QPassSignals = eLazyBoolYes;
357 else if (x == "multiprocess+")
358 m_supports_multiprocess = eLazyBoolYes;
359 else if (x == "memory-tagging+")
360 m_supports_memory_tagging = eLazyBoolYes;
361 // Look for a list of compressions in the features list e.g.
362 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
363 // deflate,lzma
364 else if (x.consume_front("SupportedCompressions=")) {
365 llvm::SmallVector<llvm::StringRef, 4> compressions;
366 x.split(compressions, ',');
367 if (!compressions.empty())
368 MaybeEnableCompression(compressions);
369 } else if (x.consume_front("PacketSize=")) {
370 StringExtractorGDBRemote packet_response(x);
371 m_max_packet_size =
372 packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
373 if (m_max_packet_size == 0) {
374 m_max_packet_size = UINT64_MAX; // Must have been a garbled response
375 Log *log(
376 ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
377 LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
378 }
379 }
380 }
381 }
382 }
383
GetThreadSuffixSupported()384 bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
385 if (m_supports_thread_suffix == eLazyBoolCalculate) {
386 StringExtractorGDBRemote response;
387 m_supports_thread_suffix = eLazyBoolNo;
388 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response) ==
389 PacketResult::Success) {
390 if (response.IsOKResponse())
391 m_supports_thread_suffix = eLazyBoolYes;
392 }
393 }
394 return m_supports_thread_suffix;
395 }
GetVContSupported(char flavor)396 bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
397 if (m_supports_vCont_c == eLazyBoolCalculate) {
398 StringExtractorGDBRemote response;
399 m_supports_vCont_any = eLazyBoolNo;
400 m_supports_vCont_all = eLazyBoolNo;
401 m_supports_vCont_c = eLazyBoolNo;
402 m_supports_vCont_C = eLazyBoolNo;
403 m_supports_vCont_s = eLazyBoolNo;
404 m_supports_vCont_S = eLazyBoolNo;
405 if (SendPacketAndWaitForResponse("vCont?", response) ==
406 PacketResult::Success) {
407 const char *response_cstr = response.GetStringRef().data();
408 if (::strstr(response_cstr, ";c"))
409 m_supports_vCont_c = eLazyBoolYes;
410
411 if (::strstr(response_cstr, ";C"))
412 m_supports_vCont_C = eLazyBoolYes;
413
414 if (::strstr(response_cstr, ";s"))
415 m_supports_vCont_s = eLazyBoolYes;
416
417 if (::strstr(response_cstr, ";S"))
418 m_supports_vCont_S = eLazyBoolYes;
419
420 if (m_supports_vCont_c == eLazyBoolYes &&
421 m_supports_vCont_C == eLazyBoolYes &&
422 m_supports_vCont_s == eLazyBoolYes &&
423 m_supports_vCont_S == eLazyBoolYes) {
424 m_supports_vCont_all = eLazyBoolYes;
425 }
426
427 if (m_supports_vCont_c == eLazyBoolYes ||
428 m_supports_vCont_C == eLazyBoolYes ||
429 m_supports_vCont_s == eLazyBoolYes ||
430 m_supports_vCont_S == eLazyBoolYes) {
431 m_supports_vCont_any = eLazyBoolYes;
432 }
433 }
434 }
435
436 switch (flavor) {
437 case 'a':
438 return m_supports_vCont_any;
439 case 'A':
440 return m_supports_vCont_all;
441 case 'c':
442 return m_supports_vCont_c;
443 case 'C':
444 return m_supports_vCont_C;
445 case 's':
446 return m_supports_vCont_s;
447 case 'S':
448 return m_supports_vCont_S;
449 default:
450 break;
451 }
452 return false;
453 }
454
455 GDBRemoteCommunication::PacketResult
SendThreadSpecificPacketAndWaitForResponse(lldb::tid_t tid,StreamString && payload,StringExtractorGDBRemote & response)456 GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
457 lldb::tid_t tid, StreamString &&payload,
458 StringExtractorGDBRemote &response) {
459 Lock lock(*this);
460 if (!lock) {
461 if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
462 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
463 LLDB_LOGF(log,
464 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
465 "for %s packet.",
466 __FUNCTION__, payload.GetData());
467 return PacketResult::ErrorNoSequenceLock;
468 }
469
470 if (GetThreadSuffixSupported())
471 payload.Printf(";thread:%4.4" PRIx64 ";", tid);
472 else {
473 if (!SetCurrentThread(tid))
474 return PacketResult::ErrorSendFailed;
475 }
476
477 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
478 }
479
480 // Check if the target supports 'p' packet. It sends out a 'p' packet and
481 // checks the response. A normal packet will tell us that support is available.
482 //
483 // Takes a valid thread ID because p needs to apply to a thread.
GetpPacketSupported(lldb::tid_t tid)484 bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
485 if (m_supports_p == eLazyBoolCalculate)
486 m_supports_p = GetThreadPacketSupported(tid, "p0");
487 return m_supports_p;
488 }
489
GetThreadPacketSupported(lldb::tid_t tid,llvm::StringRef packetStr)490 LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported(
491 lldb::tid_t tid, llvm::StringRef packetStr) {
492 StreamString payload;
493 payload.PutCString(packetStr);
494 StringExtractorGDBRemote response;
495 if (SendThreadSpecificPacketAndWaitForResponse(
496 tid, std::move(payload), response) == PacketResult::Success &&
497 response.IsNormalResponse()) {
498 return eLazyBoolYes;
499 }
500 return eLazyBoolNo;
501 }
502
GetThreadsInfo()503 StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
504 // Get information on all threads at one using the "jThreadsInfo" packet
505 StructuredData::ObjectSP object_sp;
506
507 if (m_supports_jThreadsInfo) {
508 StringExtractorGDBRemote response;
509 response.SetResponseValidatorToJSON();
510 if (SendPacketAndWaitForResponse("jThreadsInfo", response) ==
511 PacketResult::Success) {
512 if (response.IsUnsupportedResponse()) {
513 m_supports_jThreadsInfo = false;
514 } else if (!response.Empty()) {
515 object_sp =
516 StructuredData::ParseJSON(std::string(response.GetStringRef()));
517 }
518 }
519 }
520 return object_sp;
521 }
522
GetThreadExtendedInfoSupported()523 bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
524 if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
525 StringExtractorGDBRemote response;
526 m_supports_jThreadExtendedInfo = eLazyBoolNo;
527 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response) ==
528 PacketResult::Success) {
529 if (response.IsOKResponse()) {
530 m_supports_jThreadExtendedInfo = eLazyBoolYes;
531 }
532 }
533 }
534 return m_supports_jThreadExtendedInfo;
535 }
536
EnableErrorStringInPacket()537 void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
538 if (m_supports_error_string_reply == eLazyBoolCalculate) {
539 StringExtractorGDBRemote response;
540 // We try to enable error strings in remote packets but if we fail, we just
541 // work in the older way.
542 m_supports_error_string_reply = eLazyBoolNo;
543 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) ==
544 PacketResult::Success) {
545 if (response.IsOKResponse()) {
546 m_supports_error_string_reply = eLazyBoolYes;
547 }
548 }
549 }
550 }
551
GetLoadedDynamicLibrariesInfosSupported()552 bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
553 if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
554 StringExtractorGDBRemote response;
555 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
556 if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
557 response) == PacketResult::Success) {
558 if (response.IsOKResponse()) {
559 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
560 }
561 }
562 }
563 return m_supports_jLoadedDynamicLibrariesInfos;
564 }
565
GetSharedCacheInfoSupported()566 bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
567 if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
568 StringExtractorGDBRemote response;
569 m_supports_jGetSharedCacheInfo = eLazyBoolNo;
570 if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response) ==
571 PacketResult::Success) {
572 if (response.IsOKResponse()) {
573 m_supports_jGetSharedCacheInfo = eLazyBoolYes;
574 }
575 }
576 }
577 return m_supports_jGetSharedCacheInfo;
578 }
579
GetMemoryTaggingSupported()580 bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {
581 if (m_supports_memory_tagging == eLazyBoolCalculate) {
582 GetRemoteQSupported();
583 }
584 return m_supports_memory_tagging == eLazyBoolYes;
585 }
586
ReadMemoryTags(lldb::addr_t addr,size_t len,int32_t type)587 DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr,
588 size_t len,
589 int32_t type) {
590 StreamString packet;
591 packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type);
592 StringExtractorGDBRemote response;
593
594 Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_MEMORY);
595
596 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
597 PacketResult::Success ||
598 !response.IsNormalResponse()) {
599 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",
600 __FUNCTION__);
601 return nullptr;
602 }
603
604 // We are expecting
605 // m<hex encoded bytes>
606
607 if (response.GetChar() != 'm') {
608 LLDB_LOGF(log,
609 "GDBRemoteCommunicationClient::%s: qMemTags response did not "
610 "begin with \"m\"",
611 __FUNCTION__);
612 return nullptr;
613 }
614
615 size_t expected_bytes = response.GetBytesLeft() / 2;
616 DataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));
617 size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());
618 // Check both because in some situations chars are consumed even
619 // if the decoding fails.
620 if (response.GetBytesLeft() || (expected_bytes != got_bytes)) {
621 LLDB_LOGF(
622 log,
623 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
624 __FUNCTION__);
625 return nullptr;
626 }
627
628 return buffer_sp;
629 }
630
WriteMemoryTags(lldb::addr_t addr,size_t len,int32_t type,const std::vector<uint8_t> & tags)631 Status GDBRemoteCommunicationClient::WriteMemoryTags(
632 lldb::addr_t addr, size_t len, int32_t type,
633 const std::vector<uint8_t> &tags) {
634 // Format QMemTags:address,length:type:tags
635 StreamString packet;
636 packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type);
637 packet.PutBytesAsRawHex8(tags.data(), tags.size());
638
639 Status status;
640 StringExtractorGDBRemote response;
641 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
642 PacketResult::Success ||
643 !response.IsOKResponse()) {
644 status.SetErrorString("QMemTags packet failed");
645 }
646 return status;
647 }
648
GetxPacketSupported()649 bool GDBRemoteCommunicationClient::GetxPacketSupported() {
650 if (m_supports_x == eLazyBoolCalculate) {
651 StringExtractorGDBRemote response;
652 m_supports_x = eLazyBoolNo;
653 char packet[256];
654 snprintf(packet, sizeof(packet), "x0,0");
655 if (SendPacketAndWaitForResponse(packet, response) ==
656 PacketResult::Success) {
657 if (response.IsOKResponse())
658 m_supports_x = eLazyBoolYes;
659 }
660 }
661 return m_supports_x;
662 }
663
664 GDBRemoteCommunicationClient::PacketResult
SendPacketsAndConcatenateResponses(const char * payload_prefix,std::string & response_string)665 GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
666 const char *payload_prefix, std::string &response_string) {
667 Lock lock(*this);
668 if (!lock) {
669 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
670 GDBR_LOG_PACKETS));
671 LLDB_LOGF(log,
672 "error: failed to get packet sequence mutex, not sending "
673 "packets with prefix '%s'",
674 payload_prefix);
675 return PacketResult::ErrorNoSequenceLock;
676 }
677
678 response_string = "";
679 std::string payload_prefix_str(payload_prefix);
680 unsigned int response_size = 0x1000;
681 if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
682 response_size = GetRemoteMaxPacketSize();
683 }
684
685 for (unsigned int offset = 0; true; offset += response_size) {
686 StringExtractorGDBRemote this_response;
687 // Construct payload
688 char sizeDescriptor[128];
689 snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset,
690 response_size);
691 PacketResult result = SendPacketAndWaitForResponseNoLock(
692 payload_prefix_str + sizeDescriptor, this_response);
693 if (result != PacketResult::Success)
694 return result;
695
696 const std::string &this_string = std::string(this_response.GetStringRef());
697
698 // Check for m or l as first character; l seems to mean this is the last
699 // chunk
700 char first_char = *this_string.c_str();
701 if (first_char != 'm' && first_char != 'l') {
702 return PacketResult::ErrorReplyInvalid;
703 }
704 // Concatenate the result so far (skipping 'm' or 'l')
705 response_string.append(this_string, 1, std::string::npos);
706 if (first_char == 'l')
707 // We're done
708 return PacketResult::Success;
709 }
710 }
711
GetCurrentProcessID(bool allow_lazy)712 lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
713 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
714 return m_curr_pid;
715
716 // First try to retrieve the pid via the qProcessInfo request.
717 GetCurrentProcessInfo(allow_lazy);
718 if (m_curr_pid_is_valid == eLazyBoolYes) {
719 // We really got it.
720 return m_curr_pid;
721 } else {
722 // If we don't get a response for qProcessInfo, check if $qC gives us a
723 // result. $qC only returns a real process id on older debugserver and
724 // lldb-platform stubs. The gdb remote protocol documents $qC as returning
725 // the thread id, which newer debugserver and lldb-gdbserver stubs return
726 // correctly.
727 StringExtractorGDBRemote response;
728 if (SendPacketAndWaitForResponse("qC", response) == PacketResult::Success) {
729 if (response.GetChar() == 'Q') {
730 if (response.GetChar() == 'C') {
731 m_curr_pid_run = m_curr_pid =
732 response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);
733 if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
734 m_curr_pid_is_valid = eLazyBoolYes;
735 return m_curr_pid;
736 }
737 }
738 }
739 }
740
741 // If we don't get a response for $qC, check if $qfThreadID gives us a
742 // result.
743 if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
744 bool sequence_mutex_unavailable;
745 auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
746 if (!ids.empty() && !sequence_mutex_unavailable) {
747 // If server returned an explicit PID, use that.
748 m_curr_pid_run = m_curr_pid = ids.front().first;
749 // Otherwise, use the TID of the first thread (Linux hack).
750 if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
751 m_curr_pid_run = m_curr_pid = ids.front().second;
752 m_curr_pid_is_valid = eLazyBoolYes;
753 return m_curr_pid;
754 }
755 }
756 }
757
758 return LLDB_INVALID_PROCESS_ID;
759 }
760
GetLaunchSuccess(std::string & error_str)761 bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
762 error_str.clear();
763 StringExtractorGDBRemote response;
764 if (SendPacketAndWaitForResponse("qLaunchSuccess", response) ==
765 PacketResult::Success) {
766 if (response.IsOKResponse())
767 return true;
768 if (response.GetChar() == 'E') {
769 // A string the describes what failed when launching...
770 error_str = std::string(response.GetStringRef().substr(1));
771 } else {
772 error_str.assign("unknown error occurred launching process");
773 }
774 } else {
775 error_str.assign("timed out waiting for app to launch");
776 }
777 return false;
778 }
779
SendArgumentsPacket(const ProcessLaunchInfo & launch_info)780 int GDBRemoteCommunicationClient::SendArgumentsPacket(
781 const ProcessLaunchInfo &launch_info) {
782 // Since we don't get the send argv0 separate from the executable path, we
783 // need to make sure to use the actual executable path found in the
784 // launch_info...
785 std::vector<const char *> argv;
786 FileSpec exe_file = launch_info.GetExecutableFile();
787 std::string exe_path;
788 const char *arg = nullptr;
789 const Args &launch_args = launch_info.GetArguments();
790 if (exe_file)
791 exe_path = exe_file.GetPath(false);
792 else {
793 arg = launch_args.GetArgumentAtIndex(0);
794 if (arg)
795 exe_path = arg;
796 }
797 if (!exe_path.empty()) {
798 argv.push_back(exe_path.c_str());
799 for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != nullptr;
800 ++i) {
801 if (arg)
802 argv.push_back(arg);
803 }
804 }
805 if (!argv.empty()) {
806 StreamString packet;
807 packet.PutChar('A');
808 for (size_t i = 0, n = argv.size(); i < n; ++i) {
809 arg = argv[i];
810 const int arg_len = strlen(arg);
811 if (i > 0)
812 packet.PutChar(',');
813 packet.Printf("%i,%i,", arg_len * 2, (int)i);
814 packet.PutBytesAsRawHex8(arg, arg_len);
815 }
816
817 StringExtractorGDBRemote response;
818 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
819 PacketResult::Success) {
820 if (response.IsOKResponse())
821 return 0;
822 uint8_t error = response.GetError();
823 if (error)
824 return error;
825 }
826 }
827 return -1;
828 }
829
SendEnvironment(const Environment & env)830 int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {
831 for (const auto &KV : env) {
832 int r = SendEnvironmentPacket(Environment::compose(KV).c_str());
833 if (r != 0)
834 return r;
835 }
836 return 0;
837 }
838
SendEnvironmentPacket(char const * name_equal_value)839 int GDBRemoteCommunicationClient::SendEnvironmentPacket(
840 char const *name_equal_value) {
841 if (name_equal_value && name_equal_value[0]) {
842 StreamString packet;
843 bool send_hex_encoding = false;
844 for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
845 ++p) {
846 if (llvm::isPrint(*p)) {
847 switch (*p) {
848 case '$':
849 case '#':
850 case '*':
851 case '}':
852 send_hex_encoding = true;
853 break;
854 default:
855 break;
856 }
857 } else {
858 // We have non printable characters, lets hex encode this...
859 send_hex_encoding = true;
860 }
861 }
862
863 StringExtractorGDBRemote response;
864 if (send_hex_encoding) {
865 if (m_supports_QEnvironmentHexEncoded) {
866 packet.PutCString("QEnvironmentHexEncoded:");
867 packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
868 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
869 PacketResult::Success) {
870 if (response.IsOKResponse())
871 return 0;
872 uint8_t error = response.GetError();
873 if (error)
874 return error;
875 if (response.IsUnsupportedResponse())
876 m_supports_QEnvironmentHexEncoded = false;
877 }
878 }
879
880 } else if (m_supports_QEnvironment) {
881 packet.Printf("QEnvironment:%s", name_equal_value);
882 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
883 PacketResult::Success) {
884 if (response.IsOKResponse())
885 return 0;
886 uint8_t error = response.GetError();
887 if (error)
888 return error;
889 if (response.IsUnsupportedResponse())
890 m_supports_QEnvironment = false;
891 }
892 }
893 }
894 return -1;
895 }
896
SendLaunchArchPacket(char const * arch)897 int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
898 if (arch && arch[0]) {
899 StreamString packet;
900 packet.Printf("QLaunchArch:%s", arch);
901 StringExtractorGDBRemote response;
902 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
903 PacketResult::Success) {
904 if (response.IsOKResponse())
905 return 0;
906 uint8_t error = response.GetError();
907 if (error)
908 return error;
909 }
910 }
911 return -1;
912 }
913
SendLaunchEventDataPacket(char const * data,bool * was_supported)914 int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
915 char const *data, bool *was_supported) {
916 if (data && *data != '\0') {
917 StreamString packet;
918 packet.Printf("QSetProcessEvent:%s", data);
919 StringExtractorGDBRemote response;
920 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
921 PacketResult::Success) {
922 if (response.IsOKResponse()) {
923 if (was_supported)
924 *was_supported = true;
925 return 0;
926 } else if (response.IsUnsupportedResponse()) {
927 if (was_supported)
928 *was_supported = false;
929 return -1;
930 } else {
931 uint8_t error = response.GetError();
932 if (was_supported)
933 *was_supported = true;
934 if (error)
935 return error;
936 }
937 }
938 }
939 return -1;
940 }
941
GetOSVersion()942 llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
943 GetHostInfo();
944 return m_os_version;
945 }
946
GetMacCatalystVersion()947 llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {
948 GetHostInfo();
949 return m_maccatalyst_version;
950 }
951
GetOSBuildString(std::string & s)952 bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
953 if (GetHostInfo()) {
954 if (!m_os_build.empty()) {
955 s = m_os_build;
956 return true;
957 }
958 }
959 s.clear();
960 return false;
961 }
962
GetOSKernelDescription(std::string & s)963 bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
964 if (GetHostInfo()) {
965 if (!m_os_kernel.empty()) {
966 s = m_os_kernel;
967 return true;
968 }
969 }
970 s.clear();
971 return false;
972 }
973
GetHostname(std::string & s)974 bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
975 if (GetHostInfo()) {
976 if (!m_hostname.empty()) {
977 s = m_hostname;
978 return true;
979 }
980 }
981 s.clear();
982 return false;
983 }
984
GetSystemArchitecture()985 ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
986 if (GetHostInfo())
987 return m_host_arch;
988 return ArchSpec();
989 }
990
991 const lldb_private::ArchSpec &
GetProcessArchitecture()992 GDBRemoteCommunicationClient::GetProcessArchitecture() {
993 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
994 GetCurrentProcessInfo();
995 return m_process_arch;
996 }
997
GetGDBServerVersion()998 bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
999 if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
1000 m_gdb_server_name.clear();
1001 m_gdb_server_version = 0;
1002 m_qGDBServerVersion_is_valid = eLazyBoolNo;
1003
1004 StringExtractorGDBRemote response;
1005 if (SendPacketAndWaitForResponse("qGDBServerVersion", response) ==
1006 PacketResult::Success) {
1007 if (response.IsNormalResponse()) {
1008 llvm::StringRef name, value;
1009 bool success = false;
1010 while (response.GetNameColonValue(name, value)) {
1011 if (name.equals("name")) {
1012 success = true;
1013 m_gdb_server_name = std::string(value);
1014 } else if (name.equals("version")) {
1015 llvm::StringRef major, minor;
1016 std::tie(major, minor) = value.split('.');
1017 if (!major.getAsInteger(0, m_gdb_server_version))
1018 success = true;
1019 }
1020 }
1021 if (success)
1022 m_qGDBServerVersion_is_valid = eLazyBoolYes;
1023 }
1024 }
1025 }
1026 return m_qGDBServerVersion_is_valid == eLazyBoolYes;
1027 }
1028
MaybeEnableCompression(llvm::ArrayRef<llvm::StringRef> supported_compressions)1029 void GDBRemoteCommunicationClient::MaybeEnableCompression(
1030 llvm::ArrayRef<llvm::StringRef> supported_compressions) {
1031 CompressionType avail_type = CompressionType::None;
1032 llvm::StringRef avail_name;
1033
1034 #if defined(HAVE_LIBCOMPRESSION)
1035 if (avail_type == CompressionType::None) {
1036 for (auto compression : supported_compressions) {
1037 if (compression == "lzfse") {
1038 avail_type = CompressionType::LZFSE;
1039 avail_name = compression;
1040 break;
1041 }
1042 }
1043 }
1044 #endif
1045
1046 #if defined(HAVE_LIBCOMPRESSION)
1047 if (avail_type == CompressionType::None) {
1048 for (auto compression : supported_compressions) {
1049 if (compression == "zlib-deflate") {
1050 avail_type = CompressionType::ZlibDeflate;
1051 avail_name = compression;
1052 break;
1053 }
1054 }
1055 }
1056 #endif
1057
1058 #if LLVM_ENABLE_ZLIB
1059 if (avail_type == CompressionType::None) {
1060 for (auto compression : supported_compressions) {
1061 if (compression == "zlib-deflate") {
1062 avail_type = CompressionType::ZlibDeflate;
1063 avail_name = compression;
1064 break;
1065 }
1066 }
1067 }
1068 #endif
1069
1070 #if defined(HAVE_LIBCOMPRESSION)
1071 if (avail_type == CompressionType::None) {
1072 for (auto compression : supported_compressions) {
1073 if (compression == "lz4") {
1074 avail_type = CompressionType::LZ4;
1075 avail_name = compression;
1076 break;
1077 }
1078 }
1079 }
1080 #endif
1081
1082 #if defined(HAVE_LIBCOMPRESSION)
1083 if (avail_type == CompressionType::None) {
1084 for (auto compression : supported_compressions) {
1085 if (compression == "lzma") {
1086 avail_type = CompressionType::LZMA;
1087 avail_name = compression;
1088 break;
1089 }
1090 }
1091 }
1092 #endif
1093
1094 if (avail_type != CompressionType::None) {
1095 StringExtractorGDBRemote response;
1096 llvm::Twine packet = "QEnableCompression:type:" + avail_name + ";";
1097 if (SendPacketAndWaitForResponse(packet.str(), response) !=
1098 PacketResult::Success)
1099 return;
1100
1101 if (response.IsOKResponse()) {
1102 m_compression_type = avail_type;
1103 }
1104 }
1105 }
1106
GetGDBServerProgramName()1107 const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
1108 if (GetGDBServerVersion()) {
1109 if (!m_gdb_server_name.empty())
1110 return m_gdb_server_name.c_str();
1111 }
1112 return nullptr;
1113 }
1114
GetGDBServerProgramVersion()1115 uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
1116 if (GetGDBServerVersion())
1117 return m_gdb_server_version;
1118 return 0;
1119 }
1120
GetDefaultThreadId(lldb::tid_t & tid)1121 bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
1122 StringExtractorGDBRemote response;
1123 if (SendPacketAndWaitForResponse("qC", response) != PacketResult::Success)
1124 return false;
1125
1126 if (!response.IsNormalResponse())
1127 return false;
1128
1129 if (response.GetChar() == 'Q' && response.GetChar() == 'C') {
1130 auto pid_tid = response.GetPidTid(0);
1131 if (!pid_tid)
1132 return false;
1133
1134 lldb::pid_t pid = pid_tid->first;
1135 // invalid
1136 if (pid == StringExtractorGDBRemote::AllProcesses)
1137 return false;
1138
1139 // if we get pid as well, update m_curr_pid
1140 if (pid != 0) {
1141 m_curr_pid_run = m_curr_pid = pid;
1142 m_curr_pid_is_valid = eLazyBoolYes;
1143 }
1144 tid = pid_tid->second;
1145 }
1146
1147 return true;
1148 }
1149
ParseOSType(llvm::StringRef value,std::string & os_name,std::string & environment)1150 static void ParseOSType(llvm::StringRef value, std::string &os_name,
1151 std::string &environment) {
1152 if (value.equals("iossimulator") || value.equals("tvossimulator") ||
1153 value.equals("watchossimulator")) {
1154 environment = "simulator";
1155 os_name = value.drop_back(environment.size()).str();
1156 } else if (value.equals("maccatalyst")) {
1157 os_name = "ios";
1158 environment = "macabi";
1159 } else {
1160 os_name = value.str();
1161 }
1162 }
1163
GetHostInfo(bool force)1164 bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
1165 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
1166
1167 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
1168 // host info computation can require DNS traffic and shelling out to external processes.
1169 // Increase the timeout to account for that.
1170 ScopedTimeout timeout(*this, seconds(10));
1171 m_qHostInfo_is_valid = eLazyBoolNo;
1172 StringExtractorGDBRemote response;
1173 if (SendPacketAndWaitForResponse("qHostInfo", response) ==
1174 PacketResult::Success) {
1175 if (response.IsNormalResponse()) {
1176 llvm::StringRef name;
1177 llvm::StringRef value;
1178 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1179 uint32_t sub = 0;
1180 std::string arch_name;
1181 std::string os_name;
1182 std::string environment;
1183 std::string vendor_name;
1184 std::string triple;
1185 std::string distribution_id;
1186 uint32_t pointer_byte_size = 0;
1187 ByteOrder byte_order = eByteOrderInvalid;
1188 uint32_t num_keys_decoded = 0;
1189 while (response.GetNameColonValue(name, value)) {
1190 if (name.equals("cputype")) {
1191 // exception type in big endian hex
1192 if (!value.getAsInteger(0, cpu))
1193 ++num_keys_decoded;
1194 } else if (name.equals("cpusubtype")) {
1195 // exception count in big endian hex
1196 if (!value.getAsInteger(0, sub))
1197 ++num_keys_decoded;
1198 } else if (name.equals("arch")) {
1199 arch_name = std::string(value);
1200 ++num_keys_decoded;
1201 } else if (name.equals("triple")) {
1202 StringExtractor extractor(value);
1203 extractor.GetHexByteString(triple);
1204 ++num_keys_decoded;
1205 } else if (name.equals("distribution_id")) {
1206 StringExtractor extractor(value);
1207 extractor.GetHexByteString(distribution_id);
1208 ++num_keys_decoded;
1209 } else if (name.equals("os_build")) {
1210 StringExtractor extractor(value);
1211 extractor.GetHexByteString(m_os_build);
1212 ++num_keys_decoded;
1213 } else if (name.equals("hostname")) {
1214 StringExtractor extractor(value);
1215 extractor.GetHexByteString(m_hostname);
1216 ++num_keys_decoded;
1217 } else if (name.equals("os_kernel")) {
1218 StringExtractor extractor(value);
1219 extractor.GetHexByteString(m_os_kernel);
1220 ++num_keys_decoded;
1221 } else if (name.equals("ostype")) {
1222 ParseOSType(value, os_name, environment);
1223 ++num_keys_decoded;
1224 } else if (name.equals("vendor")) {
1225 vendor_name = std::string(value);
1226 ++num_keys_decoded;
1227 } else if (name.equals("endian")) {
1228 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
1229 .Case("little", eByteOrderLittle)
1230 .Case("big", eByteOrderBig)
1231 .Case("pdp", eByteOrderPDP)
1232 .Default(eByteOrderInvalid);
1233 if (byte_order != eByteOrderInvalid)
1234 ++num_keys_decoded;
1235 } else if (name.equals("ptrsize")) {
1236 if (!value.getAsInteger(0, pointer_byte_size))
1237 ++num_keys_decoded;
1238 } else if (name.equals("addressing_bits")) {
1239 if (!value.getAsInteger(0, m_addressing_bits))
1240 ++num_keys_decoded;
1241 } else if (name.equals("os_version") ||
1242 name.equals("version")) // Older debugserver binaries used
1243 // the "version" key instead of
1244 // "os_version"...
1245 {
1246 if (!m_os_version.tryParse(value))
1247 ++num_keys_decoded;
1248 } else if (name.equals("maccatalyst_version")) {
1249 if (!m_maccatalyst_version.tryParse(value))
1250 ++num_keys_decoded;
1251 } else if (name.equals("watchpoint_exceptions_received")) {
1252 m_watchpoints_trigger_after_instruction =
1253 llvm::StringSwitch<LazyBool>(value)
1254 .Case("before", eLazyBoolNo)
1255 .Case("after", eLazyBoolYes)
1256 .Default(eLazyBoolCalculate);
1257 if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
1258 ++num_keys_decoded;
1259 } else if (name.equals("default_packet_timeout")) {
1260 uint32_t timeout_seconds;
1261 if (!value.getAsInteger(0, timeout_seconds)) {
1262 m_default_packet_timeout = seconds(timeout_seconds);
1263 SetPacketTimeout(m_default_packet_timeout);
1264 ++num_keys_decoded;
1265 }
1266 } else if (name.equals("vm-page-size")) {
1267 int page_size;
1268 if (!value.getAsInteger(0, page_size)) {
1269 m_target_vm_page_size = page_size;
1270 ++num_keys_decoded;
1271 }
1272 }
1273 }
1274
1275 if (num_keys_decoded > 0)
1276 m_qHostInfo_is_valid = eLazyBoolYes;
1277
1278 if (triple.empty()) {
1279 if (arch_name.empty()) {
1280 if (cpu != LLDB_INVALID_CPUTYPE) {
1281 m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
1282 if (pointer_byte_size) {
1283 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1284 }
1285 if (byte_order != eByteOrderInvalid) {
1286 assert(byte_order == m_host_arch.GetByteOrder());
1287 }
1288
1289 if (!vendor_name.empty())
1290 m_host_arch.GetTriple().setVendorName(
1291 llvm::StringRef(vendor_name));
1292 if (!os_name.empty())
1293 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
1294 if (!environment.empty())
1295 m_host_arch.GetTriple().setEnvironmentName(environment);
1296 }
1297 } else {
1298 std::string triple;
1299 triple += arch_name;
1300 if (!vendor_name.empty() || !os_name.empty()) {
1301 triple += '-';
1302 if (vendor_name.empty())
1303 triple += "unknown";
1304 else
1305 triple += vendor_name;
1306 triple += '-';
1307 if (os_name.empty())
1308 triple += "unknown";
1309 else
1310 triple += os_name;
1311 }
1312 m_host_arch.SetTriple(triple.c_str());
1313
1314 llvm::Triple &host_triple = m_host_arch.GetTriple();
1315 if (host_triple.getVendor() == llvm::Triple::Apple &&
1316 host_triple.getOS() == llvm::Triple::Darwin) {
1317 switch (m_host_arch.GetMachine()) {
1318 case llvm::Triple::aarch64:
1319 case llvm::Triple::aarch64_32:
1320 case llvm::Triple::arm:
1321 case llvm::Triple::thumb:
1322 host_triple.setOS(llvm::Triple::IOS);
1323 break;
1324 default:
1325 host_triple.setOS(llvm::Triple::MacOSX);
1326 break;
1327 }
1328 }
1329 if (pointer_byte_size) {
1330 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1331 }
1332 if (byte_order != eByteOrderInvalid) {
1333 assert(byte_order == m_host_arch.GetByteOrder());
1334 }
1335 }
1336 } else {
1337 m_host_arch.SetTriple(triple.c_str());
1338 if (pointer_byte_size) {
1339 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
1340 }
1341 if (byte_order != eByteOrderInvalid) {
1342 assert(byte_order == m_host_arch.GetByteOrder());
1343 }
1344
1345 LLDB_LOGF(log,
1346 "GDBRemoteCommunicationClient::%s parsed host "
1347 "architecture as %s, triple as %s from triple text %s",
1348 __FUNCTION__,
1349 m_host_arch.GetArchitectureName()
1350 ? m_host_arch.GetArchitectureName()
1351 : "<null-arch-name>",
1352 m_host_arch.GetTriple().getTriple().c_str(),
1353 triple.c_str());
1354 }
1355 if (!distribution_id.empty())
1356 m_host_arch.SetDistributionId(distribution_id.c_str());
1357 }
1358 }
1359 }
1360 return m_qHostInfo_is_valid == eLazyBoolYes;
1361 }
1362
SendAttach(lldb::pid_t pid,StringExtractorGDBRemote & response)1363 int GDBRemoteCommunicationClient::SendAttach(
1364 lldb::pid_t pid, StringExtractorGDBRemote &response) {
1365 if (pid != LLDB_INVALID_PROCESS_ID) {
1366 char packet[64];
1367 const int packet_len =
1368 ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
1369 UNUSED_IF_ASSERT_DISABLED(packet_len);
1370 assert(packet_len < (int)sizeof(packet));
1371 if (SendPacketAndWaitForResponse(packet, response) ==
1372 PacketResult::Success) {
1373 if (response.IsErrorResponse())
1374 return response.GetError();
1375 return 0;
1376 }
1377 }
1378 return -1;
1379 }
1380
SendStdinNotification(const char * data,size_t data_len)1381 int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
1382 size_t data_len) {
1383 StreamString packet;
1384 packet.PutCString("I");
1385 packet.PutBytesAsRawHex8(data, data_len);
1386 StringExtractorGDBRemote response;
1387 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1388 PacketResult::Success) {
1389 return 0;
1390 }
1391 return response.GetError();
1392 }
1393
1394 const lldb_private::ArchSpec &
GetHostArchitecture()1395 GDBRemoteCommunicationClient::GetHostArchitecture() {
1396 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1397 GetHostInfo();
1398 return m_host_arch;
1399 }
1400
GetAddressingBits()1401 uint32_t GDBRemoteCommunicationClient::GetAddressingBits() {
1402 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1403 GetHostInfo();
1404 return m_addressing_bits;
1405 }
GetHostDefaultPacketTimeout()1406 seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
1407 if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1408 GetHostInfo();
1409 return m_default_packet_timeout;
1410 }
1411
AllocateMemory(size_t size,uint32_t permissions)1412 addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
1413 uint32_t permissions) {
1414 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1415 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1416 char packet[64];
1417 const int packet_len = ::snprintf(
1418 packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
1419 permissions & lldb::ePermissionsReadable ? "r" : "",
1420 permissions & lldb::ePermissionsWritable ? "w" : "",
1421 permissions & lldb::ePermissionsExecutable ? "x" : "");
1422 assert(packet_len < (int)sizeof(packet));
1423 UNUSED_IF_ASSERT_DISABLED(packet_len);
1424 StringExtractorGDBRemote response;
1425 if (SendPacketAndWaitForResponse(packet, response) ==
1426 PacketResult::Success) {
1427 if (response.IsUnsupportedResponse())
1428 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1429 else if (!response.IsErrorResponse())
1430 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1431 } else {
1432 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1433 }
1434 }
1435 return LLDB_INVALID_ADDRESS;
1436 }
1437
DeallocateMemory(addr_t addr)1438 bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
1439 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
1440 m_supports_alloc_dealloc_memory = eLazyBoolYes;
1441 char packet[64];
1442 const int packet_len =
1443 ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1444 assert(packet_len < (int)sizeof(packet));
1445 UNUSED_IF_ASSERT_DISABLED(packet_len);
1446 StringExtractorGDBRemote response;
1447 if (SendPacketAndWaitForResponse(packet, response) ==
1448 PacketResult::Success) {
1449 if (response.IsUnsupportedResponse())
1450 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1451 else if (response.IsOKResponse())
1452 return true;
1453 } else {
1454 m_supports_alloc_dealloc_memory = eLazyBoolNo;
1455 }
1456 }
1457 return false;
1458 }
1459
Detach(bool keep_stopped)1460 Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
1461 Status error;
1462
1463 if (keep_stopped) {
1464 if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
1465 char packet[64];
1466 const int packet_len =
1467 ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1468 assert(packet_len < (int)sizeof(packet));
1469 UNUSED_IF_ASSERT_DISABLED(packet_len);
1470 StringExtractorGDBRemote response;
1471 if (SendPacketAndWaitForResponse(packet, response) ==
1472 PacketResult::Success &&
1473 response.IsOKResponse()) {
1474 m_supports_detach_stay_stopped = eLazyBoolYes;
1475 } else {
1476 m_supports_detach_stay_stopped = eLazyBoolNo;
1477 }
1478 }
1479
1480 if (m_supports_detach_stay_stopped == eLazyBoolNo) {
1481 error.SetErrorString("Stays stopped not supported by this target.");
1482 return error;
1483 } else {
1484 StringExtractorGDBRemote response;
1485 PacketResult packet_result = SendPacketAndWaitForResponse("D1", response);
1486 if (packet_result != PacketResult::Success)
1487 error.SetErrorString("Sending extended disconnect packet failed.");
1488 }
1489 } else {
1490 StringExtractorGDBRemote response;
1491 PacketResult packet_result = SendPacketAndWaitForResponse("D", response);
1492 if (packet_result != PacketResult::Success)
1493 error.SetErrorString("Sending disconnect packet failed.");
1494 }
1495 return error;
1496 }
1497
GetMemoryRegionInfo(lldb::addr_t addr,lldb_private::MemoryRegionInfo & region_info)1498 Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
1499 lldb::addr_t addr, lldb_private::MemoryRegionInfo ®ion_info) {
1500 Status error;
1501 region_info.Clear();
1502
1503 if (m_supports_memory_region_info != eLazyBoolNo) {
1504 m_supports_memory_region_info = eLazyBoolYes;
1505 char packet[64];
1506 const int packet_len = ::snprintf(
1507 packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1508 assert(packet_len < (int)sizeof(packet));
1509 UNUSED_IF_ASSERT_DISABLED(packet_len);
1510 StringExtractorGDBRemote response;
1511 if (SendPacketAndWaitForResponse(packet, response) ==
1512 PacketResult::Success &&
1513 response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
1514 llvm::StringRef name;
1515 llvm::StringRef value;
1516 addr_t addr_value = LLDB_INVALID_ADDRESS;
1517 bool success = true;
1518 bool saw_permissions = false;
1519 while (success && response.GetNameColonValue(name, value)) {
1520 if (name.equals("start")) {
1521 if (!value.getAsInteger(16, addr_value))
1522 region_info.GetRange().SetRangeBase(addr_value);
1523 } else if (name.equals("size")) {
1524 if (!value.getAsInteger(16, addr_value))
1525 region_info.GetRange().SetByteSize(addr_value);
1526 } else if (name.equals("permissions") &&
1527 region_info.GetRange().IsValid()) {
1528 saw_permissions = true;
1529 if (region_info.GetRange().Contains(addr)) {
1530 if (value.find('r') != llvm::StringRef::npos)
1531 region_info.SetReadable(MemoryRegionInfo::eYes);
1532 else
1533 region_info.SetReadable(MemoryRegionInfo::eNo);
1534
1535 if (value.find('w') != llvm::StringRef::npos)
1536 region_info.SetWritable(MemoryRegionInfo::eYes);
1537 else
1538 region_info.SetWritable(MemoryRegionInfo::eNo);
1539
1540 if (value.find('x') != llvm::StringRef::npos)
1541 region_info.SetExecutable(MemoryRegionInfo::eYes);
1542 else
1543 region_info.SetExecutable(MemoryRegionInfo::eNo);
1544
1545 region_info.SetMapped(MemoryRegionInfo::eYes);
1546 } else {
1547 // The reported region does not contain this address -- we're
1548 // looking at an unmapped page
1549 region_info.SetReadable(MemoryRegionInfo::eNo);
1550 region_info.SetWritable(MemoryRegionInfo::eNo);
1551 region_info.SetExecutable(MemoryRegionInfo::eNo);
1552 region_info.SetMapped(MemoryRegionInfo::eNo);
1553 }
1554 } else if (name.equals("name")) {
1555 StringExtractorGDBRemote name_extractor(value);
1556 std::string name;
1557 name_extractor.GetHexByteString(name);
1558 region_info.SetName(name.c_str());
1559 } else if (name.equals("flags")) {
1560 region_info.SetMemoryTagged(MemoryRegionInfo::eNo);
1561
1562 llvm::StringRef flags = value;
1563 llvm::StringRef flag;
1564 while (flags.size()) {
1565 flags = flags.ltrim();
1566 std::tie(flag, flags) = flags.split(' ');
1567 // To account for trailing whitespace
1568 if (flag.size()) {
1569 if (flag == "mt") {
1570 region_info.SetMemoryTagged(MemoryRegionInfo::eYes);
1571 break;
1572 }
1573 }
1574 }
1575 } else if (name.equals("error")) {
1576 StringExtractorGDBRemote error_extractor(value);
1577 std::string error_string;
1578 // Now convert the HEX bytes into a string value
1579 error_extractor.GetHexByteString(error_string);
1580 error.SetErrorString(error_string.c_str());
1581 } else if (name.equals("dirty-pages")) {
1582 std::vector<addr_t> dirty_page_list;
1583 std::string comma_sep_str = value.str();
1584 size_t comma_pos;
1585 addr_t page;
1586 while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) {
1587 comma_sep_str[comma_pos] = '\0';
1588 page = StringConvert::ToUInt64(comma_sep_str.c_str(),
1589 LLDB_INVALID_ADDRESS, 16);
1590 if (page != LLDB_INVALID_ADDRESS)
1591 dirty_page_list.push_back(page);
1592 comma_sep_str.erase(0, comma_pos + 1);
1593 }
1594 page = StringConvert::ToUInt64(comma_sep_str.c_str(),
1595 LLDB_INVALID_ADDRESS, 16);
1596 if (page != LLDB_INVALID_ADDRESS)
1597 dirty_page_list.push_back(page);
1598 region_info.SetDirtyPageList(dirty_page_list);
1599 }
1600 }
1601
1602 if (m_target_vm_page_size != 0)
1603 region_info.SetPageSize(m_target_vm_page_size);
1604
1605 if (region_info.GetRange().IsValid()) {
1606 // We got a valid address range back but no permissions -- which means
1607 // this is an unmapped page
1608 if (!saw_permissions) {
1609 region_info.SetReadable(MemoryRegionInfo::eNo);
1610 region_info.SetWritable(MemoryRegionInfo::eNo);
1611 region_info.SetExecutable(MemoryRegionInfo::eNo);
1612 region_info.SetMapped(MemoryRegionInfo::eNo);
1613 }
1614 } else {
1615 // We got an invalid address range back
1616 error.SetErrorString("Server returned invalid range");
1617 }
1618 } else {
1619 m_supports_memory_region_info = eLazyBoolNo;
1620 }
1621 }
1622
1623 if (m_supports_memory_region_info == eLazyBoolNo) {
1624 error.SetErrorString("qMemoryRegionInfo is not supported");
1625 }
1626
1627 // Try qXfer:memory-map:read to get region information not included in
1628 // qMemoryRegionInfo
1629 MemoryRegionInfo qXfer_region_info;
1630 Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);
1631
1632 if (error.Fail()) {
1633 // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
1634 // the qXfer result as a fallback
1635 if (qXfer_error.Success()) {
1636 region_info = qXfer_region_info;
1637 error.Clear();
1638 } else {
1639 region_info.Clear();
1640 }
1641 } else if (qXfer_error.Success()) {
1642 // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
1643 // both regions are the same range, update the result to include the flash-
1644 // memory information that is specific to the qXfer result.
1645 if (region_info.GetRange() == qXfer_region_info.GetRange()) {
1646 region_info.SetFlash(qXfer_region_info.GetFlash());
1647 region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
1648 }
1649 }
1650 return error;
1651 }
1652
GetQXferMemoryMapRegionInfo(lldb::addr_t addr,MemoryRegionInfo & region)1653 Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
1654 lldb::addr_t addr, MemoryRegionInfo ®ion) {
1655 Status error = LoadQXferMemoryMap();
1656 if (!error.Success())
1657 return error;
1658 for (const auto &map_region : m_qXfer_memory_map) {
1659 if (map_region.GetRange().Contains(addr)) {
1660 region = map_region;
1661 return error;
1662 }
1663 }
1664 error.SetErrorString("Region not found");
1665 return error;
1666 }
1667
LoadQXferMemoryMap()1668 Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {
1669
1670 Status error;
1671
1672 if (m_qXfer_memory_map_loaded)
1673 // Already loaded, return success
1674 return error;
1675
1676 if (!XMLDocument::XMLEnabled()) {
1677 error.SetErrorString("XML is not supported");
1678 return error;
1679 }
1680
1681 if (!GetQXferMemoryMapReadSupported()) {
1682 error.SetErrorString("Memory map is not supported");
1683 return error;
1684 }
1685
1686 std::string xml;
1687 lldb_private::Status lldberr;
1688 if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml,
1689 lldberr)) {
1690 error.SetErrorString("Failed to read memory map");
1691 return error;
1692 }
1693
1694 XMLDocument xml_document;
1695
1696 if (!xml_document.ParseMemory(xml.c_str(), xml.size())) {
1697 error.SetErrorString("Failed to parse memory map xml");
1698 return error;
1699 }
1700
1701 XMLNode map_node = xml_document.GetRootElement("memory-map");
1702 if (!map_node) {
1703 error.SetErrorString("Invalid root node in memory map xml");
1704 return error;
1705 }
1706
1707 m_qXfer_memory_map.clear();
1708
1709 map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
1710 if (!memory_node.IsElement())
1711 return true;
1712 if (memory_node.GetName() != "memory")
1713 return true;
1714 auto type = memory_node.GetAttributeValue("type", "");
1715 uint64_t start;
1716 uint64_t length;
1717 if (!memory_node.GetAttributeValueAsUnsigned("start", start))
1718 return true;
1719 if (!memory_node.GetAttributeValueAsUnsigned("length", length))
1720 return true;
1721 MemoryRegionInfo region;
1722 region.GetRange().SetRangeBase(start);
1723 region.GetRange().SetByteSize(length);
1724 if (type == "rom") {
1725 region.SetReadable(MemoryRegionInfo::eYes);
1726 this->m_qXfer_memory_map.push_back(region);
1727 } else if (type == "ram") {
1728 region.SetReadable(MemoryRegionInfo::eYes);
1729 region.SetWritable(MemoryRegionInfo::eYes);
1730 this->m_qXfer_memory_map.push_back(region);
1731 } else if (type == "flash") {
1732 region.SetFlash(MemoryRegionInfo::eYes);
1733 memory_node.ForEachChildElement(
1734 [®ion](const XMLNode &prop_node) -> bool {
1735 if (!prop_node.IsElement())
1736 return true;
1737 if (prop_node.GetName() != "property")
1738 return true;
1739 auto propname = prop_node.GetAttributeValue("name", "");
1740 if (propname == "blocksize") {
1741 uint64_t blocksize;
1742 if (prop_node.GetElementTextAsUnsigned(blocksize))
1743 region.SetBlocksize(blocksize);
1744 }
1745 return true;
1746 });
1747 this->m_qXfer_memory_map.push_back(region);
1748 }
1749 return true;
1750 });
1751
1752 m_qXfer_memory_map_loaded = true;
1753
1754 return error;
1755 }
1756
GetWatchpointSupportInfo(uint32_t & num)1757 Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
1758 Status error;
1759
1760 if (m_supports_watchpoint_support_info == eLazyBoolYes) {
1761 num = m_num_supported_hardware_watchpoints;
1762 return error;
1763 }
1764
1765 // Set num to 0 first.
1766 num = 0;
1767 if (m_supports_watchpoint_support_info != eLazyBoolNo) {
1768 StringExtractorGDBRemote response;
1769 if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) ==
1770 PacketResult::Success) {
1771 m_supports_watchpoint_support_info = eLazyBoolYes;
1772 llvm::StringRef name;
1773 llvm::StringRef value;
1774 bool found_num_field = false;
1775 while (response.GetNameColonValue(name, value)) {
1776 if (name.equals("num")) {
1777 value.getAsInteger(0, m_num_supported_hardware_watchpoints);
1778 num = m_num_supported_hardware_watchpoints;
1779 found_num_field = true;
1780 }
1781 }
1782 if (!found_num_field) {
1783 m_supports_watchpoint_support_info = eLazyBoolNo;
1784 }
1785 } else {
1786 m_supports_watchpoint_support_info = eLazyBoolNo;
1787 }
1788 }
1789
1790 if (m_supports_watchpoint_support_info == eLazyBoolNo) {
1791 error.SetErrorString("qWatchpointSupportInfo is not supported");
1792 }
1793 return error;
1794 }
1795
GetWatchpointSupportInfo(uint32_t & num,bool & after,const ArchSpec & arch)1796 lldb_private::Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(
1797 uint32_t &num, bool &after, const ArchSpec &arch) {
1798 Status error(GetWatchpointSupportInfo(num));
1799 if (error.Success())
1800 error = GetWatchpointsTriggerAfterInstruction(after, arch);
1801 return error;
1802 }
1803
1804 lldb_private::Status
GetWatchpointsTriggerAfterInstruction(bool & after,const ArchSpec & arch)1805 GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
1806 bool &after, const ArchSpec &arch) {
1807 Status error;
1808 llvm::Triple triple = arch.GetTriple();
1809
1810 // we assume watchpoints will happen after running the relevant opcode and we
1811 // only want to override this behavior if we have explicitly received a
1812 // qHostInfo telling us otherwise
1813 if (m_qHostInfo_is_valid != eLazyBoolYes) {
1814 // On targets like MIPS and ppc64, watchpoint exceptions are always
1815 // generated before the instruction is executed. The connected target may
1816 // not support qHostInfo or qWatchpointSupportInfo packets.
1817 after = !(triple.isMIPS() || triple.isPPC64());
1818 } else {
1819 // For MIPS and ppc64, set m_watchpoints_trigger_after_instruction to
1820 // eLazyBoolNo if it is not calculated before.
1821 if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
1822 (triple.isMIPS() || triple.isPPC64()))
1823 m_watchpoints_trigger_after_instruction = eLazyBoolNo;
1824
1825 after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1826 }
1827 return error;
1828 }
1829
SetSTDIN(const FileSpec & file_spec)1830 int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
1831 if (file_spec) {
1832 std::string path{file_spec.GetPath(false)};
1833 StreamString packet;
1834 packet.PutCString("QSetSTDIN:");
1835 packet.PutStringAsRawHex8(path);
1836
1837 StringExtractorGDBRemote response;
1838 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1839 PacketResult::Success) {
1840 if (response.IsOKResponse())
1841 return 0;
1842 uint8_t error = response.GetError();
1843 if (error)
1844 return error;
1845 }
1846 }
1847 return -1;
1848 }
1849
SetSTDOUT(const FileSpec & file_spec)1850 int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
1851 if (file_spec) {
1852 std::string path{file_spec.GetPath(false)};
1853 StreamString packet;
1854 packet.PutCString("QSetSTDOUT:");
1855 packet.PutStringAsRawHex8(path);
1856
1857 StringExtractorGDBRemote response;
1858 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1859 PacketResult::Success) {
1860 if (response.IsOKResponse())
1861 return 0;
1862 uint8_t error = response.GetError();
1863 if (error)
1864 return error;
1865 }
1866 }
1867 return -1;
1868 }
1869
SetSTDERR(const FileSpec & file_spec)1870 int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
1871 if (file_spec) {
1872 std::string path{file_spec.GetPath(false)};
1873 StreamString packet;
1874 packet.PutCString("QSetSTDERR:");
1875 packet.PutStringAsRawHex8(path);
1876
1877 StringExtractorGDBRemote response;
1878 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1879 PacketResult::Success) {
1880 if (response.IsOKResponse())
1881 return 0;
1882 uint8_t error = response.GetError();
1883 if (error)
1884 return error;
1885 }
1886 }
1887 return -1;
1888 }
1889
GetWorkingDir(FileSpec & working_dir)1890 bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
1891 StringExtractorGDBRemote response;
1892 if (SendPacketAndWaitForResponse("qGetWorkingDir", response) ==
1893 PacketResult::Success) {
1894 if (response.IsUnsupportedResponse())
1895 return false;
1896 if (response.IsErrorResponse())
1897 return false;
1898 std::string cwd;
1899 response.GetHexByteString(cwd);
1900 working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
1901 return !cwd.empty();
1902 }
1903 return false;
1904 }
1905
SetWorkingDir(const FileSpec & working_dir)1906 int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
1907 if (working_dir) {
1908 std::string path{working_dir.GetPath(false)};
1909 StreamString packet;
1910 packet.PutCString("QSetWorkingDir:");
1911 packet.PutStringAsRawHex8(path);
1912
1913 StringExtractorGDBRemote response;
1914 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
1915 PacketResult::Success) {
1916 if (response.IsOKResponse())
1917 return 0;
1918 uint8_t error = response.GetError();
1919 if (error)
1920 return error;
1921 }
1922 }
1923 return -1;
1924 }
1925
SetDisableASLR(bool enable)1926 int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
1927 char packet[32];
1928 const int packet_len =
1929 ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
1930 assert(packet_len < (int)sizeof(packet));
1931 UNUSED_IF_ASSERT_DISABLED(packet_len);
1932 StringExtractorGDBRemote response;
1933 if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
1934 if (response.IsOKResponse())
1935 return 0;
1936 uint8_t error = response.GetError();
1937 if (error)
1938 return error;
1939 }
1940 return -1;
1941 }
1942
SetDetachOnError(bool enable)1943 int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
1944 char packet[32];
1945 const int packet_len = ::snprintf(packet, sizeof(packet),
1946 "QSetDetachOnError:%i", enable ? 1 : 0);
1947 assert(packet_len < (int)sizeof(packet));
1948 UNUSED_IF_ASSERT_DISABLED(packet_len);
1949 StringExtractorGDBRemote response;
1950 if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
1951 if (response.IsOKResponse())
1952 return 0;
1953 uint8_t error = response.GetError();
1954 if (error)
1955 return error;
1956 }
1957 return -1;
1958 }
1959
DecodeProcessInfoResponse(StringExtractorGDBRemote & response,ProcessInstanceInfo & process_info)1960 bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
1961 StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
1962 if (response.IsNormalResponse()) {
1963 llvm::StringRef name;
1964 llvm::StringRef value;
1965 StringExtractor extractor;
1966
1967 uint32_t cpu = LLDB_INVALID_CPUTYPE;
1968 uint32_t sub = 0;
1969 std::string vendor;
1970 std::string os_type;
1971
1972 while (response.GetNameColonValue(name, value)) {
1973 if (name.equals("pid")) {
1974 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1975 value.getAsInteger(0, pid);
1976 process_info.SetProcessID(pid);
1977 } else if (name.equals("ppid")) {
1978 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1979 value.getAsInteger(0, pid);
1980 process_info.SetParentProcessID(pid);
1981 } else if (name.equals("uid")) {
1982 uint32_t uid = UINT32_MAX;
1983 value.getAsInteger(0, uid);
1984 process_info.SetUserID(uid);
1985 } else if (name.equals("euid")) {
1986 uint32_t uid = UINT32_MAX;
1987 value.getAsInteger(0, uid);
1988 process_info.SetEffectiveUserID(uid);
1989 } else if (name.equals("gid")) {
1990 uint32_t gid = UINT32_MAX;
1991 value.getAsInteger(0, gid);
1992 process_info.SetGroupID(gid);
1993 } else if (name.equals("egid")) {
1994 uint32_t gid = UINT32_MAX;
1995 value.getAsInteger(0, gid);
1996 process_info.SetEffectiveGroupID(gid);
1997 } else if (name.equals("triple")) {
1998 StringExtractor extractor(value);
1999 std::string triple;
2000 extractor.GetHexByteString(triple);
2001 process_info.GetArchitecture().SetTriple(triple.c_str());
2002 } else if (name.equals("name")) {
2003 StringExtractor extractor(value);
2004 // The process name from ASCII hex bytes since we can't control the
2005 // characters in a process name
2006 std::string name;
2007 extractor.GetHexByteString(name);
2008 process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
2009 } else if (name.equals("args")) {
2010 llvm::StringRef encoded_args(value), hex_arg;
2011
2012 bool is_arg0 = true;
2013 while (!encoded_args.empty()) {
2014 std::tie(hex_arg, encoded_args) = encoded_args.split('-');
2015 std::string arg;
2016 StringExtractor extractor(hex_arg);
2017 if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {
2018 // In case of wrong encoding, we discard all the arguments
2019 process_info.GetArguments().Clear();
2020 process_info.SetArg0("");
2021 break;
2022 }
2023 if (is_arg0)
2024 process_info.SetArg0(arg);
2025 else
2026 process_info.GetArguments().AppendArgument(arg);
2027 is_arg0 = false;
2028 }
2029 } else if (name.equals("cputype")) {
2030 value.getAsInteger(0, cpu);
2031 } else if (name.equals("cpusubtype")) {
2032 value.getAsInteger(0, sub);
2033 } else if (name.equals("vendor")) {
2034 vendor = std::string(value);
2035 } else if (name.equals("ostype")) {
2036 os_type = std::string(value);
2037 }
2038 }
2039
2040 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
2041 if (vendor == "apple") {
2042 process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,
2043 sub);
2044 process_info.GetArchitecture().GetTriple().setVendorName(
2045 llvm::StringRef(vendor));
2046 process_info.GetArchitecture().GetTriple().setOSName(
2047 llvm::StringRef(os_type));
2048 }
2049 }
2050
2051 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
2052 return true;
2053 }
2054 return false;
2055 }
2056
GetProcessInfo(lldb::pid_t pid,ProcessInstanceInfo & process_info)2057 bool GDBRemoteCommunicationClient::GetProcessInfo(
2058 lldb::pid_t pid, ProcessInstanceInfo &process_info) {
2059 process_info.Clear();
2060
2061 if (m_supports_qProcessInfoPID) {
2062 char packet[32];
2063 const int packet_len =
2064 ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
2065 assert(packet_len < (int)sizeof(packet));
2066 UNUSED_IF_ASSERT_DISABLED(packet_len);
2067 StringExtractorGDBRemote response;
2068 if (SendPacketAndWaitForResponse(packet, response) ==
2069 PacketResult::Success) {
2070 return DecodeProcessInfoResponse(response, process_info);
2071 } else {
2072 m_supports_qProcessInfoPID = false;
2073 return false;
2074 }
2075 }
2076 return false;
2077 }
2078
GetCurrentProcessInfo(bool allow_lazy)2079 bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
2080 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
2081 GDBR_LOG_PACKETS));
2082
2083 if (allow_lazy) {
2084 if (m_qProcessInfo_is_valid == eLazyBoolYes)
2085 return true;
2086 if (m_qProcessInfo_is_valid == eLazyBoolNo)
2087 return false;
2088 }
2089
2090 GetHostInfo();
2091
2092 StringExtractorGDBRemote response;
2093 if (SendPacketAndWaitForResponse("qProcessInfo", response) ==
2094 PacketResult::Success) {
2095 if (response.IsNormalResponse()) {
2096 llvm::StringRef name;
2097 llvm::StringRef value;
2098 uint32_t cpu = LLDB_INVALID_CPUTYPE;
2099 uint32_t sub = 0;
2100 std::string arch_name;
2101 std::string os_name;
2102 std::string environment;
2103 std::string vendor_name;
2104 std::string triple;
2105 std::string elf_abi;
2106 uint32_t pointer_byte_size = 0;
2107 StringExtractor extractor;
2108 ByteOrder byte_order = eByteOrderInvalid;
2109 uint32_t num_keys_decoded = 0;
2110 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
2111 while (response.GetNameColonValue(name, value)) {
2112 if (name.equals("cputype")) {
2113 if (!value.getAsInteger(16, cpu))
2114 ++num_keys_decoded;
2115 } else if (name.equals("cpusubtype")) {
2116 if (!value.getAsInteger(16, sub))
2117 ++num_keys_decoded;
2118 } else if (name.equals("triple")) {
2119 StringExtractor extractor(value);
2120 extractor.GetHexByteString(triple);
2121 ++num_keys_decoded;
2122 } else if (name.equals("ostype")) {
2123 ParseOSType(value, os_name, environment);
2124 ++num_keys_decoded;
2125 } else if (name.equals("vendor")) {
2126 vendor_name = std::string(value);
2127 ++num_keys_decoded;
2128 } else if (name.equals("endian")) {
2129 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
2130 .Case("little", eByteOrderLittle)
2131 .Case("big", eByteOrderBig)
2132 .Case("pdp", eByteOrderPDP)
2133 .Default(eByteOrderInvalid);
2134 if (byte_order != eByteOrderInvalid)
2135 ++num_keys_decoded;
2136 } else if (name.equals("ptrsize")) {
2137 if (!value.getAsInteger(16, pointer_byte_size))
2138 ++num_keys_decoded;
2139 } else if (name.equals("pid")) {
2140 if (!value.getAsInteger(16, pid))
2141 ++num_keys_decoded;
2142 } else if (name.equals("elf_abi")) {
2143 elf_abi = std::string(value);
2144 ++num_keys_decoded;
2145 }
2146 }
2147 if (num_keys_decoded > 0)
2148 m_qProcessInfo_is_valid = eLazyBoolYes;
2149 if (pid != LLDB_INVALID_PROCESS_ID) {
2150 m_curr_pid_is_valid = eLazyBoolYes;
2151 m_curr_pid_run = m_curr_pid = pid;
2152 }
2153
2154 // Set the ArchSpec from the triple if we have it.
2155 if (!triple.empty()) {
2156 m_process_arch.SetTriple(triple.c_str());
2157 m_process_arch.SetFlags(elf_abi);
2158 if (pointer_byte_size) {
2159 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2160 }
2161 } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
2162 !vendor_name.empty()) {
2163 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
2164 if (!environment.empty())
2165 triple.setEnvironmentName(environment);
2166
2167 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
2168 assert(triple.getObjectFormat() != llvm::Triple::Wasm);
2169 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
2170 switch (triple.getObjectFormat()) {
2171 case llvm::Triple::MachO:
2172 m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
2173 break;
2174 case llvm::Triple::ELF:
2175 m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
2176 break;
2177 case llvm::Triple::COFF:
2178 m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
2179 break;
2180 case llvm::Triple::GOFF:
2181 case llvm::Triple::Wasm:
2182 case llvm::Triple::XCOFF:
2183 LLDB_LOGF(log, "error: not supported target architecture");
2184 return false;
2185 case llvm::Triple::UnknownObjectFormat:
2186 LLDB_LOGF(log, "error: failed to determine target architecture");
2187 return false;
2188 }
2189
2190 if (pointer_byte_size) {
2191 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
2192 }
2193 if (byte_order != eByteOrderInvalid) {
2194 assert(byte_order == m_process_arch.GetByteOrder());
2195 }
2196 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2197 m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2198 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2199 m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
2200 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
2201 m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
2202 }
2203 return true;
2204 }
2205 } else {
2206 m_qProcessInfo_is_valid = eLazyBoolNo;
2207 }
2208
2209 return false;
2210 }
2211
FindProcesses(const ProcessInstanceInfoMatch & match_info,ProcessInstanceInfoList & process_infos)2212 uint32_t GDBRemoteCommunicationClient::FindProcesses(
2213 const ProcessInstanceInfoMatch &match_info,
2214 ProcessInstanceInfoList &process_infos) {
2215 process_infos.clear();
2216
2217 if (m_supports_qfProcessInfo) {
2218 StreamString packet;
2219 packet.PutCString("qfProcessInfo");
2220 if (!match_info.MatchAllProcesses()) {
2221 packet.PutChar(':');
2222 const char *name = match_info.GetProcessInfo().GetName();
2223 bool has_name_match = false;
2224 if (name && name[0]) {
2225 has_name_match = true;
2226 NameMatch name_match_type = match_info.GetNameMatchType();
2227 switch (name_match_type) {
2228 case NameMatch::Ignore:
2229 has_name_match = false;
2230 break;
2231
2232 case NameMatch::Equals:
2233 packet.PutCString("name_match:equals;");
2234 break;
2235
2236 case NameMatch::Contains:
2237 packet.PutCString("name_match:contains;");
2238 break;
2239
2240 case NameMatch::StartsWith:
2241 packet.PutCString("name_match:starts_with;");
2242 break;
2243
2244 case NameMatch::EndsWith:
2245 packet.PutCString("name_match:ends_with;");
2246 break;
2247
2248 case NameMatch::RegularExpression:
2249 packet.PutCString("name_match:regex;");
2250 break;
2251 }
2252 if (has_name_match) {
2253 packet.PutCString("name:");
2254 packet.PutBytesAsRawHex8(name, ::strlen(name));
2255 packet.PutChar(';');
2256 }
2257 }
2258
2259 if (match_info.GetProcessInfo().ProcessIDIsValid())
2260 packet.Printf("pid:%" PRIu64 ";",
2261 match_info.GetProcessInfo().GetProcessID());
2262 if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2263 packet.Printf("parent_pid:%" PRIu64 ";",
2264 match_info.GetProcessInfo().GetParentProcessID());
2265 if (match_info.GetProcessInfo().UserIDIsValid())
2266 packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
2267 if (match_info.GetProcessInfo().GroupIDIsValid())
2268 packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
2269 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2270 packet.Printf("euid:%u;",
2271 match_info.GetProcessInfo().GetEffectiveUserID());
2272 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2273 packet.Printf("egid:%u;",
2274 match_info.GetProcessInfo().GetEffectiveGroupID());
2275 packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
2276 if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
2277 const ArchSpec &match_arch =
2278 match_info.GetProcessInfo().GetArchitecture();
2279 const llvm::Triple &triple = match_arch.GetTriple();
2280 packet.PutCString("triple:");
2281 packet.PutCString(triple.getTriple());
2282 packet.PutChar(';');
2283 }
2284 }
2285 StringExtractorGDBRemote response;
2286 // Increase timeout as the first qfProcessInfo packet takes a long time on
2287 // Android. The value of 1min was arrived at empirically.
2288 ScopedTimeout timeout(*this, minutes(1));
2289 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
2290 PacketResult::Success) {
2291 do {
2292 ProcessInstanceInfo process_info;
2293 if (!DecodeProcessInfoResponse(response, process_info))
2294 break;
2295 process_infos.push_back(process_info);
2296 response = StringExtractorGDBRemote();
2297 } while (SendPacketAndWaitForResponse("qsProcessInfo", response) ==
2298 PacketResult::Success);
2299 } else {
2300 m_supports_qfProcessInfo = false;
2301 return 0;
2302 }
2303 }
2304 return process_infos.size();
2305 }
2306
GetUserName(uint32_t uid,std::string & name)2307 bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
2308 std::string &name) {
2309 if (m_supports_qUserName) {
2310 char packet[32];
2311 const int packet_len =
2312 ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
2313 assert(packet_len < (int)sizeof(packet));
2314 UNUSED_IF_ASSERT_DISABLED(packet_len);
2315 StringExtractorGDBRemote response;
2316 if (SendPacketAndWaitForResponse(packet, response) ==
2317 PacketResult::Success) {
2318 if (response.IsNormalResponse()) {
2319 // Make sure we parsed the right number of characters. The response is
2320 // the hex encoded user name and should make up the entire packet. If
2321 // there are any non-hex ASCII bytes, the length won't match below..
2322 if (response.GetHexByteString(name) * 2 ==
2323 response.GetStringRef().size())
2324 return true;
2325 }
2326 } else {
2327 m_supports_qUserName = false;
2328 return false;
2329 }
2330 }
2331 return false;
2332 }
2333
GetGroupName(uint32_t gid,std::string & name)2334 bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
2335 std::string &name) {
2336 if (m_supports_qGroupName) {
2337 char packet[32];
2338 const int packet_len =
2339 ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
2340 assert(packet_len < (int)sizeof(packet));
2341 UNUSED_IF_ASSERT_DISABLED(packet_len);
2342 StringExtractorGDBRemote response;
2343 if (SendPacketAndWaitForResponse(packet, response) ==
2344 PacketResult::Success) {
2345 if (response.IsNormalResponse()) {
2346 // Make sure we parsed the right number of characters. The response is
2347 // the hex encoded group name and should make up the entire packet. If
2348 // there are any non-hex ASCII bytes, the length won't match below..
2349 if (response.GetHexByteString(name) * 2 ==
2350 response.GetStringRef().size())
2351 return true;
2352 }
2353 } else {
2354 m_supports_qGroupName = false;
2355 return false;
2356 }
2357 }
2358 return false;
2359 }
2360
SetNonStopMode(const bool enable)2361 bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
2362 // Form non-stop packet request
2363 char packet[32];
2364 const int packet_len =
2365 ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
2366 assert(packet_len < (int)sizeof(packet));
2367 UNUSED_IF_ASSERT_DISABLED(packet_len);
2368
2369 StringExtractorGDBRemote response;
2370 // Send to target
2371 if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success)
2372 if (response.IsOKResponse())
2373 return true;
2374
2375 // Failed or not supported
2376 return false;
2377 }
2378
MakeSpeedTestPacket(StreamString & packet,uint32_t send_size,uint32_t recv_size)2379 static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
2380 uint32_t recv_size) {
2381 packet.Clear();
2382 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2383 uint32_t bytes_left = send_size;
2384 while (bytes_left > 0) {
2385 if (bytes_left >= 26) {
2386 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2387 bytes_left -= 26;
2388 } else {
2389 packet.Printf("%*.*s;", bytes_left, bytes_left,
2390 "abcdefghijklmnopqrstuvwxyz");
2391 bytes_left = 0;
2392 }
2393 }
2394 }
2395
2396 duration<float>
calculate_standard_deviation(const std::vector<duration<float>> & v)2397 calculate_standard_deviation(const std::vector<duration<float>> &v) {
2398 using Dur = duration<float>;
2399 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
2400 Dur mean = sum / v.size();
2401 float accum = 0;
2402 for (auto d : v) {
2403 float delta = (d - mean).count();
2404 accum += delta * delta;
2405 };
2406
2407 return Dur(sqrtf(accum / (v.size() - 1)));
2408 }
2409
TestPacketSpeed(const uint32_t num_packets,uint32_t max_send,uint32_t max_recv,uint64_t recv_amount,bool json,Stream & strm)2410 void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
2411 uint32_t max_send,
2412 uint32_t max_recv,
2413 uint64_t recv_amount,
2414 bool json, Stream &strm) {
2415 uint32_t i;
2416 if (SendSpeedTestPacket(0, 0)) {
2417 StreamString packet;
2418 if (json)
2419 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "
2420 "\"results\" : [",
2421 num_packets);
2422 else
2423 strm.Printf("Testing sending %u packets of various sizes:\n",
2424 num_packets);
2425 strm.Flush();
2426
2427 uint32_t result_idx = 0;
2428 uint32_t send_size;
2429 std::vector<duration<float>> packet_times;
2430
2431 for (send_size = 0; send_size <= max_send;
2432 send_size ? send_size *= 2 : send_size = 4) {
2433 for (uint32_t recv_size = 0; recv_size <= max_recv;
2434 recv_size ? recv_size *= 2 : recv_size = 4) {
2435 MakeSpeedTestPacket(packet, send_size, recv_size);
2436
2437 packet_times.clear();
2438 // Test how long it takes to send 'num_packets' packets
2439 const auto start_time = steady_clock::now();
2440 for (i = 0; i < num_packets; ++i) {
2441 const auto packet_start_time = steady_clock::now();
2442 StringExtractorGDBRemote response;
2443 SendPacketAndWaitForResponse(packet.GetString(), response);
2444 const auto packet_end_time = steady_clock::now();
2445 packet_times.push_back(packet_end_time - packet_start_time);
2446 }
2447 const auto end_time = steady_clock::now();
2448 const auto total_time = end_time - start_time;
2449
2450 float packets_per_second =
2451 ((float)num_packets) / duration<float>(total_time).count();
2452 auto average_per_packet = total_time / num_packets;
2453 const duration<float> standard_deviation =
2454 calculate_standard_deviation(packet_times);
2455 if (json) {
2456 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2457 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
2458 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
2459 result_idx > 0 ? "," : "", send_size, recv_size,
2460 total_time, standard_deviation);
2461 ++result_idx;
2462 } else {
2463 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
2464 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
2465 "standard deviation of {5,10:ms+f6}\n",
2466 send_size, recv_size, duration<float>(total_time),
2467 packets_per_second, duration<float>(average_per_packet),
2468 standard_deviation);
2469 }
2470 strm.Flush();
2471 }
2472 }
2473
2474 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
2475 if (json)
2476 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "
2477 ": %" PRIu64 ",\n \"results\" : [",
2478 recv_amount);
2479 else
2480 strm.Printf("Testing receiving %2.1fMB of data using varying receive "
2481 "packet sizes:\n",
2482 k_recv_amount_mb);
2483 strm.Flush();
2484 send_size = 0;
2485 result_idx = 0;
2486 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
2487 MakeSpeedTestPacket(packet, send_size, recv_size);
2488
2489 // If we have a receive size, test how long it takes to receive 4MB of
2490 // data
2491 if (recv_size > 0) {
2492 const auto start_time = steady_clock::now();
2493 uint32_t bytes_read = 0;
2494 uint32_t packet_count = 0;
2495 while (bytes_read < recv_amount) {
2496 StringExtractorGDBRemote response;
2497 SendPacketAndWaitForResponse(packet.GetString(), response);
2498 bytes_read += recv_size;
2499 ++packet_count;
2500 }
2501 const auto end_time = steady_clock::now();
2502 const auto total_time = end_time - start_time;
2503 float mb_second = ((float)recv_amount) /
2504 duration<float>(total_time).count() /
2505 (1024.0 * 1024.0);
2506 float packets_per_second =
2507 ((float)packet_count) / duration<float>(total_time).count();
2508 const auto average_per_packet = total_time / packet_count;
2509
2510 if (json) {
2511 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "
2512 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
2513 result_idx > 0 ? "," : "", send_size, recv_size,
2514 total_time);
2515 ++result_idx;
2516 } else {
2517 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
2518 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
2519 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
2520 send_size, recv_size, packet_count, k_recv_amount_mb,
2521 duration<float>(total_time), mb_second,
2522 packets_per_second, duration<float>(average_per_packet));
2523 }
2524 strm.Flush();
2525 }
2526 }
2527 if (json)
2528 strm.Printf("\n ]\n }\n}\n");
2529 else
2530 strm.EOL();
2531 }
2532 }
2533
SendSpeedTestPacket(uint32_t send_size,uint32_t recv_size)2534 bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
2535 uint32_t recv_size) {
2536 StreamString packet;
2537 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
2538 uint32_t bytes_left = send_size;
2539 while (bytes_left > 0) {
2540 if (bytes_left >= 26) {
2541 packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2542 bytes_left -= 26;
2543 } else {
2544 packet.Printf("%*.*s;", bytes_left, bytes_left,
2545 "abcdefghijklmnopqrstuvwxyz");
2546 bytes_left = 0;
2547 }
2548 }
2549
2550 StringExtractorGDBRemote response;
2551 return SendPacketAndWaitForResponse(packet.GetString(), response) ==
2552 PacketResult::Success;
2553 }
2554
LaunchGDBServer(const char * remote_accept_hostname,lldb::pid_t & pid,uint16_t & port,std::string & socket_name)2555 bool GDBRemoteCommunicationClient::LaunchGDBServer(
2556 const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
2557 std::string &socket_name) {
2558 pid = LLDB_INVALID_PROCESS_ID;
2559 port = 0;
2560 socket_name.clear();
2561
2562 StringExtractorGDBRemote response;
2563 StreamString stream;
2564 stream.PutCString("qLaunchGDBServer;");
2565 std::string hostname;
2566 if (remote_accept_hostname && remote_accept_hostname[0])
2567 hostname = remote_accept_hostname;
2568 else {
2569 if (HostInfo::GetHostname(hostname)) {
2570 // Make the GDB server we launch only accept connections from this host
2571 stream.Printf("host:%s;", hostname.c_str());
2572 } else {
2573 // Make the GDB server we launch accept connections from any host since
2574 // we can't figure out the hostname
2575 stream.Printf("host:*;");
2576 }
2577 }
2578 // give the process a few seconds to startup
2579 ScopedTimeout timeout(*this, seconds(10));
2580
2581 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
2582 PacketResult::Success) {
2583 llvm::StringRef name;
2584 llvm::StringRef value;
2585 while (response.GetNameColonValue(name, value)) {
2586 if (name.equals("port"))
2587 value.getAsInteger(0, port);
2588 else if (name.equals("pid"))
2589 value.getAsInteger(0, pid);
2590 else if (name.compare("socket_name") == 0) {
2591 StringExtractor extractor(value);
2592 extractor.GetHexByteString(socket_name);
2593 }
2594 }
2595 return true;
2596 }
2597 return false;
2598 }
2599
QueryGDBServer(std::vector<std::pair<uint16_t,std::string>> & connection_urls)2600 size_t GDBRemoteCommunicationClient::QueryGDBServer(
2601 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
2602 connection_urls.clear();
2603
2604 StringExtractorGDBRemote response;
2605 if (SendPacketAndWaitForResponse("qQueryGDBServer", response) !=
2606 PacketResult::Success)
2607 return 0;
2608
2609 StructuredData::ObjectSP data =
2610 StructuredData::ParseJSON(std::string(response.GetStringRef()));
2611 if (!data)
2612 return 0;
2613
2614 StructuredData::Array *array = data->GetAsArray();
2615 if (!array)
2616 return 0;
2617
2618 for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
2619 StructuredData::Dictionary *element = nullptr;
2620 if (!array->GetItemAtIndexAsDictionary(i, element))
2621 continue;
2622
2623 uint16_t port = 0;
2624 if (StructuredData::ObjectSP port_osp =
2625 element->GetValueForKey(llvm::StringRef("port")))
2626 port = port_osp->GetIntegerValue(0);
2627
2628 std::string socket_name;
2629 if (StructuredData::ObjectSP socket_name_osp =
2630 element->GetValueForKey(llvm::StringRef("socket_name")))
2631 socket_name = std::string(socket_name_osp->GetStringValue());
2632
2633 if (port != 0 || !socket_name.empty())
2634 connection_urls.emplace_back(port, socket_name);
2635 }
2636 return connection_urls.size();
2637 }
2638
KillSpawnedProcess(lldb::pid_t pid)2639 bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
2640 StreamString stream;
2641 stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
2642
2643 StringExtractorGDBRemote response;
2644 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
2645 PacketResult::Success) {
2646 if (response.IsOKResponse())
2647 return true;
2648 }
2649 return false;
2650 }
2651
2652 llvm::Optional<PidTid>
SendSetCurrentThreadPacket(uint64_t tid,uint64_t pid,char op)2653 GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid,
2654 uint64_t pid,
2655 char op) {
2656 lldb_private::StreamString packet;
2657 packet.PutChar('H');
2658 packet.PutChar(op);
2659
2660 if (pid != LLDB_INVALID_PROCESS_ID)
2661 packet.Printf("p%" PRIx64 ".", pid);
2662
2663 if (tid == UINT64_MAX)
2664 packet.PutCString("-1");
2665 else
2666 packet.Printf("%" PRIx64, tid);
2667
2668 StringExtractorGDBRemote response;
2669 if (SendPacketAndWaitForResponse(packet.GetString(), response)
2670 == PacketResult::Success) {
2671 if (response.IsOKResponse())
2672 return {{pid, tid}};
2673
2674 /*
2675 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2676 * Hg packet.
2677 * The reply from '?' packet could be as simple as 'S05'. There is no packet
2678 * which can
2679 * give us pid and/or tid. Assume pid=tid=1 in such cases.
2680 */
2681 if (response.IsUnsupportedResponse() && IsConnected())
2682 return {{1, 1}};
2683 }
2684 return llvm::None;
2685 }
2686
SetCurrentThread(uint64_t tid,uint64_t pid)2687 bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid,
2688 uint64_t pid) {
2689 if (m_curr_tid == tid &&
2690 (m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid))
2691 return true;
2692
2693 llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');
2694 if (ret.hasValue()) {
2695 if (ret->pid != LLDB_INVALID_PROCESS_ID)
2696 m_curr_pid = ret->pid;
2697 m_curr_tid = ret->tid;
2698 }
2699 return ret.hasValue();
2700 }
2701
SetCurrentThreadForRun(uint64_t tid,uint64_t pid)2702 bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid,
2703 uint64_t pid) {
2704 if (m_curr_tid_run == tid &&
2705 (m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid))
2706 return true;
2707
2708 llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');
2709 if (ret.hasValue()) {
2710 if (ret->pid != LLDB_INVALID_PROCESS_ID)
2711 m_curr_pid_run = ret->pid;
2712 m_curr_tid_run = ret->tid;
2713 }
2714 return ret.hasValue();
2715 }
2716
GetStopReply(StringExtractorGDBRemote & response)2717 bool GDBRemoteCommunicationClient::GetStopReply(
2718 StringExtractorGDBRemote &response) {
2719 if (SendPacketAndWaitForResponse("?", response) == PacketResult::Success)
2720 return response.IsNormalResponse();
2721 return false;
2722 }
2723
GetThreadStopInfo(lldb::tid_t tid,StringExtractorGDBRemote & response)2724 bool GDBRemoteCommunicationClient::GetThreadStopInfo(
2725 lldb::tid_t tid, StringExtractorGDBRemote &response) {
2726 if (m_supports_qThreadStopInfo) {
2727 char packet[256];
2728 int packet_len =
2729 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
2730 assert(packet_len < (int)sizeof(packet));
2731 UNUSED_IF_ASSERT_DISABLED(packet_len);
2732 if (SendPacketAndWaitForResponse(packet, response) ==
2733 PacketResult::Success) {
2734 if (response.IsUnsupportedResponse())
2735 m_supports_qThreadStopInfo = false;
2736 else if (response.IsNormalResponse())
2737 return true;
2738 else
2739 return false;
2740 } else {
2741 m_supports_qThreadStopInfo = false;
2742 }
2743 }
2744 return false;
2745 }
2746
SendGDBStoppointTypePacket(GDBStoppointType type,bool insert,addr_t addr,uint32_t length,std::chrono::seconds timeout)2747 uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
2748 GDBStoppointType type, bool insert, addr_t addr, uint32_t length,
2749 std::chrono::seconds timeout) {
2750 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
2751 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
2752 __FUNCTION__, insert ? "add" : "remove", addr);
2753
2754 // Check if the stub is known not to support this breakpoint type
2755 if (!SupportsGDBStoppointPacket(type))
2756 return UINT8_MAX;
2757 // Construct the breakpoint packet
2758 char packet[64];
2759 const int packet_len =
2760 ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
2761 insert ? 'Z' : 'z', type, addr, length);
2762 // Check we haven't overwritten the end of the packet buffer
2763 assert(packet_len + 1 < (int)sizeof(packet));
2764 UNUSED_IF_ASSERT_DISABLED(packet_len);
2765 StringExtractorGDBRemote response;
2766 // Make sure the response is either "OK", "EXX" where XX are two hex digits,
2767 // or "" (unsupported)
2768 response.SetResponseValidatorToOKErrorNotSupported();
2769 // Try to send the breakpoint packet, and check that it was correctly sent
2770 if (SendPacketAndWaitForResponse(packet, response, timeout) ==
2771 PacketResult::Success) {
2772 // Receive and OK packet when the breakpoint successfully placed
2773 if (response.IsOKResponse())
2774 return 0;
2775
2776 // Status while setting breakpoint, send back specific error
2777 if (response.IsErrorResponse())
2778 return response.GetError();
2779
2780 // Empty packet informs us that breakpoint is not supported
2781 if (response.IsUnsupportedResponse()) {
2782 // Disable this breakpoint type since it is unsupported
2783 switch (type) {
2784 case eBreakpointSoftware:
2785 m_supports_z0 = false;
2786 break;
2787 case eBreakpointHardware:
2788 m_supports_z1 = false;
2789 break;
2790 case eWatchpointWrite:
2791 m_supports_z2 = false;
2792 break;
2793 case eWatchpointRead:
2794 m_supports_z3 = false;
2795 break;
2796 case eWatchpointReadWrite:
2797 m_supports_z4 = false;
2798 break;
2799 case eStoppointInvalid:
2800 return UINT8_MAX;
2801 }
2802 }
2803 }
2804 // Signal generic failure
2805 return UINT8_MAX;
2806 }
2807
2808 std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
GetCurrentProcessAndThreadIDs(bool & sequence_mutex_unavailable)2809 GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs(
2810 bool &sequence_mutex_unavailable) {
2811 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
2812
2813 Lock lock(*this);
2814 if (lock) {
2815 sequence_mutex_unavailable = false;
2816 StringExtractorGDBRemote response;
2817
2818 PacketResult packet_result;
2819 for (packet_result =
2820 SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
2821 packet_result == PacketResult::Success && response.IsNormalResponse();
2822 packet_result =
2823 SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
2824 char ch = response.GetChar();
2825 if (ch == 'l')
2826 break;
2827 if (ch == 'm') {
2828 do {
2829 auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID);
2830 if (!pid_tid)
2831 return {};
2832
2833 ids.push_back(pid_tid.getValue());
2834 ch = response.GetChar(); // Skip the command separator
2835 } while (ch == ','); // Make sure we got a comma separator
2836 }
2837 }
2838
2839 /*
2840 * Connected bare-iron target (like YAMON gdb-stub) may not have support for
2841 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
2842 * could
2843 * be as simple as 'S05'. There is no packet which can give us pid and/or
2844 * tid.
2845 * Assume pid=tid=1 in such cases.
2846 */
2847 if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
2848 ids.size() == 0 && IsConnected()) {
2849 ids.emplace_back(1, 1);
2850 }
2851 } else {
2852 Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
2853 GDBR_LOG_PACKETS));
2854 LLDB_LOG(log, "error: failed to get packet sequence mutex, not sending "
2855 "packet 'qfThreadInfo'");
2856 sequence_mutex_unavailable = true;
2857 }
2858
2859 return ids;
2860 }
2861
GetCurrentThreadIDs(std::vector<lldb::tid_t> & thread_ids,bool & sequence_mutex_unavailable)2862 size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
2863 std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
2864 lldb::pid_t pid = GetCurrentProcessID();
2865 thread_ids.clear();
2866
2867 auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
2868 if (ids.empty() || sequence_mutex_unavailable)
2869 return 0;
2870
2871 for (auto id : ids) {
2872 // skip threads that do not belong to the current process
2873 if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid)
2874 continue;
2875 if (id.second != LLDB_INVALID_THREAD_ID &&
2876 id.second != StringExtractorGDBRemote::AllThreads)
2877 thread_ids.push_back(id.second);
2878 }
2879
2880 return thread_ids.size();
2881 }
2882
GetShlibInfoAddr()2883 lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
2884 StringExtractorGDBRemote response;
2885 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) !=
2886 PacketResult::Success ||
2887 !response.IsNormalResponse())
2888 return LLDB_INVALID_ADDRESS;
2889 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2890 }
2891
RunShellCommand(llvm::StringRef command,const FileSpec & working_dir,int * status_ptr,int * signo_ptr,std::string * command_output,const Timeout<std::micro> & timeout)2892 lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
2893 llvm::StringRef command,
2894 const FileSpec &
2895 working_dir, // Pass empty FileSpec to use the current working directory
2896 int *status_ptr, // Pass NULL if you don't want the process exit status
2897 int *signo_ptr, // Pass NULL if you don't want the signal that caused the
2898 // process to exit
2899 std::string
2900 *command_output, // Pass NULL if you don't want the command output
2901 const Timeout<std::micro> &timeout) {
2902 lldb_private::StreamString stream;
2903 stream.PutCString("qPlatform_shell:");
2904 stream.PutBytesAsRawHex8(command.data(), command.size());
2905 stream.PutChar(',');
2906 uint32_t timeout_sec = UINT32_MAX;
2907 if (timeout) {
2908 // TODO: Use chrono version of std::ceil once c++17 is available.
2909 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
2910 }
2911 stream.PutHex32(timeout_sec);
2912 if (working_dir) {
2913 std::string path{working_dir.GetPath(false)};
2914 stream.PutChar(',');
2915 stream.PutStringAsRawHex8(path);
2916 }
2917 StringExtractorGDBRemote response;
2918 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
2919 PacketResult::Success) {
2920 if (response.GetChar() != 'F')
2921 return Status("malformed reply");
2922 if (response.GetChar() != ',')
2923 return Status("malformed reply");
2924 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2925 if (exitcode == UINT32_MAX)
2926 return Status("unable to run remote process");
2927 else if (status_ptr)
2928 *status_ptr = exitcode;
2929 if (response.GetChar() != ',')
2930 return Status("malformed reply");
2931 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2932 if (signo_ptr)
2933 *signo_ptr = signo;
2934 if (response.GetChar() != ',')
2935 return Status("malformed reply");
2936 std::string output;
2937 response.GetEscapedBinaryData(output);
2938 if (command_output)
2939 command_output->assign(output);
2940 return Status();
2941 }
2942 return Status("unable to send packet");
2943 }
2944
MakeDirectory(const FileSpec & file_spec,uint32_t file_permissions)2945 Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
2946 uint32_t file_permissions) {
2947 std::string path{file_spec.GetPath(false)};
2948 lldb_private::StreamString stream;
2949 stream.PutCString("qPlatform_mkdir:");
2950 stream.PutHex32(file_permissions);
2951 stream.PutChar(',');
2952 stream.PutStringAsRawHex8(path);
2953 llvm::StringRef packet = stream.GetString();
2954 StringExtractorGDBRemote response;
2955
2956 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
2957 return Status("failed to send '%s' packet", packet.str().c_str());
2958
2959 if (response.GetChar() != 'F')
2960 return Status("invalid response to '%s' packet", packet.str().c_str());
2961
2962 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
2963 }
2964
2965 Status
SetFilePermissions(const FileSpec & file_spec,uint32_t file_permissions)2966 GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
2967 uint32_t file_permissions) {
2968 std::string path{file_spec.GetPath(false)};
2969 lldb_private::StreamString stream;
2970 stream.PutCString("qPlatform_chmod:");
2971 stream.PutHex32(file_permissions);
2972 stream.PutChar(',');
2973 stream.PutStringAsRawHex8(path);
2974 llvm::StringRef packet = stream.GetString();
2975 StringExtractorGDBRemote response;
2976
2977 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
2978 return Status("failed to send '%s' packet", stream.GetData());
2979
2980 if (response.GetChar() != 'F')
2981 return Status("invalid response to '%s' packet", stream.GetData());
2982
2983 return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
2984 }
2985
ParseHostIOPacketResponse(StringExtractorGDBRemote & response,uint64_t fail_result,Status & error)2986 static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
2987 uint64_t fail_result, Status &error) {
2988 response.SetFilePos(0);
2989 if (response.GetChar() != 'F')
2990 return fail_result;
2991 int32_t result = response.GetS32(-2);
2992 if (result == -2)
2993 return fail_result;
2994 if (response.GetChar() == ',') {
2995 int result_errno = response.GetS32(-2);
2996 if (result_errno != -2)
2997 error.SetError(result_errno, eErrorTypePOSIX);
2998 else
2999 error.SetError(-1, eErrorTypeGeneric);
3000 } else
3001 error.Clear();
3002 return result;
3003 }
3004 lldb::user_id_t
OpenFile(const lldb_private::FileSpec & file_spec,File::OpenOptions flags,mode_t mode,Status & error)3005 GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
3006 File::OpenOptions flags, mode_t mode,
3007 Status &error) {
3008 std::string path(file_spec.GetPath(false));
3009 lldb_private::StreamString stream;
3010 stream.PutCString("vFile:open:");
3011 if (path.empty())
3012 return UINT64_MAX;
3013 stream.PutStringAsRawHex8(path);
3014 stream.PutChar(',');
3015 stream.PutHex32(flags);
3016 stream.PutChar(',');
3017 stream.PutHex32(mode);
3018 StringExtractorGDBRemote response;
3019 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3020 PacketResult::Success) {
3021 return ParseHostIOPacketResponse(response, UINT64_MAX, error);
3022 }
3023 return UINT64_MAX;
3024 }
3025
CloseFile(lldb::user_id_t fd,Status & error)3026 bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,
3027 Status &error) {
3028 lldb_private::StreamString stream;
3029 stream.Printf("vFile:close:%i", (int)fd);
3030 StringExtractorGDBRemote response;
3031 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3032 PacketResult::Success) {
3033 return ParseHostIOPacketResponse(response, -1, error) == 0;
3034 }
3035 return false;
3036 }
3037
3038 // Extension of host I/O packets to get the file size.
GetFileSize(const lldb_private::FileSpec & file_spec)3039 lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
3040 const lldb_private::FileSpec &file_spec) {
3041 std::string path(file_spec.GetPath(false));
3042 lldb_private::StreamString stream;
3043 stream.PutCString("vFile:size:");
3044 stream.PutStringAsRawHex8(path);
3045 StringExtractorGDBRemote response;
3046 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3047 PacketResult::Success) {
3048 if (response.GetChar() != 'F')
3049 return UINT64_MAX;
3050 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
3051 return retcode;
3052 }
3053 return UINT64_MAX;
3054 }
3055
AutoCompleteDiskFileOrDirectory(CompletionRequest & request,bool only_dir)3056 void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory(
3057 CompletionRequest &request, bool only_dir) {
3058 lldb_private::StreamString stream;
3059 stream.PutCString("qPathComplete:");
3060 stream.PutHex32(only_dir ? 1 : 0);
3061 stream.PutChar(',');
3062 stream.PutStringAsRawHex8(request.GetCursorArgumentPrefix());
3063 StringExtractorGDBRemote response;
3064 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3065 PacketResult::Success) {
3066 StreamString strm;
3067 char ch = response.GetChar();
3068 if (ch != 'M')
3069 return;
3070 while (response.Peek()) {
3071 strm.Clear();
3072 while ((ch = response.GetHexU8(0, false)) != '\0')
3073 strm.PutChar(ch);
3074 request.AddCompletion(strm.GetString());
3075 if (response.GetChar() != ',')
3076 break;
3077 }
3078 }
3079 }
3080
3081 Status
GetFilePermissions(const FileSpec & file_spec,uint32_t & file_permissions)3082 GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
3083 uint32_t &file_permissions) {
3084 std::string path{file_spec.GetPath(false)};
3085 Status error;
3086 lldb_private::StreamString stream;
3087 stream.PutCString("vFile:mode:");
3088 stream.PutStringAsRawHex8(path);
3089 StringExtractorGDBRemote response;
3090 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3091 PacketResult::Success) {
3092 if (response.GetChar() != 'F') {
3093 error.SetErrorStringWithFormat("invalid response to '%s' packet",
3094 stream.GetData());
3095 } else {
3096 const uint32_t mode = response.GetS32(-1);
3097 if (static_cast<int32_t>(mode) == -1) {
3098 if (response.GetChar() == ',') {
3099 int response_errno = response.GetS32(-1);
3100 if (response_errno > 0)
3101 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3102 else
3103 error.SetErrorToGenericError();
3104 } else
3105 error.SetErrorToGenericError();
3106 } else {
3107 file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
3108 }
3109 }
3110 } else {
3111 error.SetErrorStringWithFormat("failed to send '%s' packet",
3112 stream.GetData());
3113 }
3114 return error;
3115 }
3116
ReadFile(lldb::user_id_t fd,uint64_t offset,void * dst,uint64_t dst_len,Status & error)3117 uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
3118 uint64_t offset, void *dst,
3119 uint64_t dst_len,
3120 Status &error) {
3121 lldb_private::StreamString stream;
3122 stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
3123 offset);
3124 StringExtractorGDBRemote response;
3125 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3126 PacketResult::Success) {
3127 if (response.GetChar() != 'F')
3128 return 0;
3129 uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
3130 if (retcode == UINT32_MAX)
3131 return retcode;
3132 const char next = (response.Peek() ? *response.Peek() : 0);
3133 if (next == ',')
3134 return 0;
3135 if (next == ';') {
3136 response.GetChar(); // skip the semicolon
3137 std::string buffer;
3138 if (response.GetEscapedBinaryData(buffer)) {
3139 const uint64_t data_to_write =
3140 std::min<uint64_t>(dst_len, buffer.size());
3141 if (data_to_write > 0)
3142 memcpy(dst, &buffer[0], data_to_write);
3143 return data_to_write;
3144 }
3145 }
3146 }
3147 return 0;
3148 }
3149
WriteFile(lldb::user_id_t fd,uint64_t offset,const void * src,uint64_t src_len,Status & error)3150 uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
3151 uint64_t offset,
3152 const void *src,
3153 uint64_t src_len,
3154 Status &error) {
3155 lldb_private::StreamGDBRemote stream;
3156 stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
3157 stream.PutEscapedBytes(src, src_len);
3158 StringExtractorGDBRemote response;
3159 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3160 PacketResult::Success) {
3161 if (response.GetChar() != 'F') {
3162 error.SetErrorStringWithFormat("write file failed");
3163 return 0;
3164 }
3165 uint64_t bytes_written = response.GetU64(UINT64_MAX);
3166 if (bytes_written == UINT64_MAX) {
3167 error.SetErrorToGenericError();
3168 if (response.GetChar() == ',') {
3169 int response_errno = response.GetS32(-1);
3170 if (response_errno > 0)
3171 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3172 }
3173 return 0;
3174 }
3175 return bytes_written;
3176 } else {
3177 error.SetErrorString("failed to send vFile:pwrite packet");
3178 }
3179 return 0;
3180 }
3181
CreateSymlink(const FileSpec & src,const FileSpec & dst)3182 Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
3183 const FileSpec &dst) {
3184 std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
3185 Status error;
3186 lldb_private::StreamGDBRemote stream;
3187 stream.PutCString("vFile:symlink:");
3188 // the unix symlink() command reverses its parameters where the dst if first,
3189 // so we follow suit here
3190 stream.PutStringAsRawHex8(dst_path);
3191 stream.PutChar(',');
3192 stream.PutStringAsRawHex8(src_path);
3193 StringExtractorGDBRemote response;
3194 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3195 PacketResult::Success) {
3196 if (response.GetChar() == 'F') {
3197 uint32_t result = response.GetU32(UINT32_MAX);
3198 if (result != 0) {
3199 error.SetErrorToGenericError();
3200 if (response.GetChar() == ',') {
3201 int response_errno = response.GetS32(-1);
3202 if (response_errno > 0)
3203 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3204 }
3205 }
3206 } else {
3207 // Should have returned with 'F<result>[,<errno>]'
3208 error.SetErrorStringWithFormat("symlink failed");
3209 }
3210 } else {
3211 error.SetErrorString("failed to send vFile:symlink packet");
3212 }
3213 return error;
3214 }
3215
Unlink(const FileSpec & file_spec)3216 Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
3217 std::string path{file_spec.GetPath(false)};
3218 Status error;
3219 lldb_private::StreamGDBRemote stream;
3220 stream.PutCString("vFile:unlink:");
3221 // the unix symlink() command reverses its parameters where the dst if first,
3222 // so we follow suit here
3223 stream.PutStringAsRawHex8(path);
3224 StringExtractorGDBRemote response;
3225 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3226 PacketResult::Success) {
3227 if (response.GetChar() == 'F') {
3228 uint32_t result = response.GetU32(UINT32_MAX);
3229 if (result != 0) {
3230 error.SetErrorToGenericError();
3231 if (response.GetChar() == ',') {
3232 int response_errno = response.GetS32(-1);
3233 if (response_errno > 0)
3234 error.SetError(response_errno, lldb::eErrorTypePOSIX);
3235 }
3236 }
3237 } else {
3238 // Should have returned with 'F<result>[,<errno>]'
3239 error.SetErrorStringWithFormat("unlink failed");
3240 }
3241 } else {
3242 error.SetErrorString("failed to send vFile:unlink packet");
3243 }
3244 return error;
3245 }
3246
3247 // Extension of host I/O packets to get whether a file exists.
GetFileExists(const lldb_private::FileSpec & file_spec)3248 bool GDBRemoteCommunicationClient::GetFileExists(
3249 const lldb_private::FileSpec &file_spec) {
3250 std::string path(file_spec.GetPath(false));
3251 lldb_private::StreamString stream;
3252 stream.PutCString("vFile:exists:");
3253 stream.PutStringAsRawHex8(path);
3254 StringExtractorGDBRemote response;
3255 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3256 PacketResult::Success) {
3257 if (response.GetChar() != 'F')
3258 return false;
3259 if (response.GetChar() != ',')
3260 return false;
3261 bool retcode = (response.GetChar() != '0');
3262 return retcode;
3263 }
3264 return false;
3265 }
3266
CalculateMD5(const lldb_private::FileSpec & file_spec,uint64_t & high,uint64_t & low)3267 bool GDBRemoteCommunicationClient::CalculateMD5(
3268 const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
3269 std::string path(file_spec.GetPath(false));
3270 lldb_private::StreamString stream;
3271 stream.PutCString("vFile:MD5:");
3272 stream.PutStringAsRawHex8(path);
3273 StringExtractorGDBRemote response;
3274 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
3275 PacketResult::Success) {
3276 if (response.GetChar() != 'F')
3277 return false;
3278 if (response.GetChar() != ',')
3279 return false;
3280 if (response.Peek() && *response.Peek() == 'x')
3281 return false;
3282 low = response.GetHexMaxU64(false, UINT64_MAX);
3283 high = response.GetHexMaxU64(false, UINT64_MAX);
3284 return true;
3285 }
3286 return false;
3287 }
3288
AvoidGPackets(ProcessGDBRemote * process)3289 bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
3290 // Some targets have issues with g/G packets and we need to avoid using them
3291 if (m_avoid_g_packets == eLazyBoolCalculate) {
3292 if (process) {
3293 m_avoid_g_packets = eLazyBoolNo;
3294 const ArchSpec &arch = process->GetTarget().GetArchitecture();
3295 if (arch.IsValid() &&
3296 arch.GetTriple().getVendor() == llvm::Triple::Apple &&
3297 arch.GetTriple().getOS() == llvm::Triple::IOS &&
3298 (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
3299 arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {
3300 m_avoid_g_packets = eLazyBoolYes;
3301 uint32_t gdb_server_version = GetGDBServerProgramVersion();
3302 if (gdb_server_version != 0) {
3303 const char *gdb_server_name = GetGDBServerProgramName();
3304 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
3305 if (gdb_server_version >= 310)
3306 m_avoid_g_packets = eLazyBoolNo;
3307 }
3308 }
3309 }
3310 }
3311 }
3312 return m_avoid_g_packets == eLazyBoolYes;
3313 }
3314
ReadRegister(lldb::tid_t tid,uint32_t reg)3315 DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
3316 uint32_t reg) {
3317 StreamString payload;
3318 payload.Printf("p%x", reg);
3319 StringExtractorGDBRemote response;
3320 if (SendThreadSpecificPacketAndWaitForResponse(
3321 tid, std::move(payload), response) != PacketResult::Success ||
3322 !response.IsNormalResponse())
3323 return nullptr;
3324
3325 DataBufferSP buffer_sp(
3326 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3327 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3328 return buffer_sp;
3329 }
3330
ReadAllRegisters(lldb::tid_t tid)3331 DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
3332 StreamString payload;
3333 payload.PutChar('g');
3334 StringExtractorGDBRemote response;
3335 if (SendThreadSpecificPacketAndWaitForResponse(
3336 tid, std::move(payload), response) != PacketResult::Success ||
3337 !response.IsNormalResponse())
3338 return nullptr;
3339
3340 DataBufferSP buffer_sp(
3341 new DataBufferHeap(response.GetStringRef().size() / 2, 0));
3342 response.GetHexBytes(buffer_sp->GetData(), '\xcc');
3343 return buffer_sp;
3344 }
3345
WriteRegister(lldb::tid_t tid,uint32_t reg_num,llvm::ArrayRef<uint8_t> data)3346 bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
3347 uint32_t reg_num,
3348 llvm::ArrayRef<uint8_t> data) {
3349 StreamString payload;
3350 payload.Printf("P%x=", reg_num);
3351 payload.PutBytesAsRawHex8(data.data(), data.size(),
3352 endian::InlHostByteOrder(),
3353 endian::InlHostByteOrder());
3354 StringExtractorGDBRemote response;
3355 return SendThreadSpecificPacketAndWaitForResponse(
3356 tid, std::move(payload), response) == PacketResult::Success &&
3357 response.IsOKResponse();
3358 }
3359
WriteAllRegisters(lldb::tid_t tid,llvm::ArrayRef<uint8_t> data)3360 bool GDBRemoteCommunicationClient::WriteAllRegisters(
3361 lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
3362 StreamString payload;
3363 payload.PutChar('G');
3364 payload.PutBytesAsRawHex8(data.data(), data.size(),
3365 endian::InlHostByteOrder(),
3366 endian::InlHostByteOrder());
3367 StringExtractorGDBRemote response;
3368 return SendThreadSpecificPacketAndWaitForResponse(
3369 tid, std::move(payload), response) == PacketResult::Success &&
3370 response.IsOKResponse();
3371 }
3372
SaveRegisterState(lldb::tid_t tid,uint32_t & save_id)3373 bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
3374 uint32_t &save_id) {
3375 save_id = 0; // Set to invalid save ID
3376 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3377 return false;
3378
3379 m_supports_QSaveRegisterState = eLazyBoolYes;
3380 StreamString payload;
3381 payload.PutCString("QSaveRegisterState");
3382 StringExtractorGDBRemote response;
3383 if (SendThreadSpecificPacketAndWaitForResponse(
3384 tid, std::move(payload), response) != PacketResult::Success)
3385 return false;
3386
3387 if (response.IsUnsupportedResponse())
3388 m_supports_QSaveRegisterState = eLazyBoolNo;
3389
3390 const uint32_t response_save_id = response.GetU32(0);
3391 if (response_save_id == 0)
3392 return false;
3393
3394 save_id = response_save_id;
3395 return true;
3396 }
3397
RestoreRegisterState(lldb::tid_t tid,uint32_t save_id)3398 bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
3399 uint32_t save_id) {
3400 // We use the "m_supports_QSaveRegisterState" variable here because the
3401 // QSaveRegisterState and QRestoreRegisterState packets must both be
3402 // supported in order to be useful
3403 if (m_supports_QSaveRegisterState == eLazyBoolNo)
3404 return false;
3405
3406 StreamString payload;
3407 payload.Printf("QRestoreRegisterState:%u", save_id);
3408 StringExtractorGDBRemote response;
3409 if (SendThreadSpecificPacketAndWaitForResponse(
3410 tid, std::move(payload), response) != PacketResult::Success)
3411 return false;
3412
3413 if (response.IsOKResponse())
3414 return true;
3415
3416 if (response.IsUnsupportedResponse())
3417 m_supports_QSaveRegisterState = eLazyBoolNo;
3418 return false;
3419 }
3420
SyncThreadState(lldb::tid_t tid)3421 bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
3422 if (!GetSyncThreadStateSupported())
3423 return false;
3424
3425 StreamString packet;
3426 StringExtractorGDBRemote response;
3427 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
3428 return SendPacketAndWaitForResponse(packet.GetString(), response) ==
3429 GDBRemoteCommunication::PacketResult::Success &&
3430 response.IsOKResponse();
3431 }
3432
3433 llvm::Expected<TraceSupportedResponse>
SendTraceSupported(std::chrono::seconds timeout)3434 GDBRemoteCommunicationClient::SendTraceSupported(std::chrono::seconds timeout) {
3435 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3436
3437 StreamGDBRemote escaped_packet;
3438 escaped_packet.PutCString("jLLDBTraceSupported");
3439
3440 StringExtractorGDBRemote response;
3441 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3442 timeout) ==
3443 GDBRemoteCommunication::PacketResult::Success) {
3444 if (response.IsErrorResponse())
3445 return response.GetStatus().ToError();
3446 if (response.IsUnsupportedResponse())
3447 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3448 "jLLDBTraceSupported is unsupported");
3449
3450 return llvm::json::parse<TraceSupportedResponse>(response.Peek(),
3451 "TraceSupportedResponse");
3452 }
3453 LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported");
3454 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3455 "failed to send packet: jLLDBTraceSupported");
3456 }
3457
3458 llvm::Error
SendTraceStop(const TraceStopRequest & request,std::chrono::seconds timeout)3459 GDBRemoteCommunicationClient::SendTraceStop(const TraceStopRequest &request,
3460 std::chrono::seconds timeout) {
3461 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3462
3463 StreamGDBRemote escaped_packet;
3464 escaped_packet.PutCString("jLLDBTraceStop:");
3465
3466 std::string json_string;
3467 llvm::raw_string_ostream os(json_string);
3468 os << toJSON(request);
3469 os.flush();
3470
3471 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3472
3473 StringExtractorGDBRemote response;
3474 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3475 timeout) ==
3476 GDBRemoteCommunication::PacketResult::Success) {
3477 if (response.IsErrorResponse())
3478 return response.GetStatus().ToError();
3479 if (response.IsUnsupportedResponse())
3480 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3481 "jLLDBTraceStop is unsupported");
3482 if (response.IsOKResponse())
3483 return llvm::Error::success();
3484 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3485 "Invalid jLLDBTraceStart response");
3486 }
3487 LLDB_LOG(log, "failed to send packet: jLLDBTraceStop");
3488 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3489 "failed to send packet: jLLDBTraceStop '%s'",
3490 escaped_packet.GetData());
3491 }
3492
3493 llvm::Error
SendTraceStart(const llvm::json::Value & params,std::chrono::seconds timeout)3494 GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value ¶ms,
3495 std::chrono::seconds timeout) {
3496 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3497
3498 StreamGDBRemote escaped_packet;
3499 escaped_packet.PutCString("jLLDBTraceStart:");
3500
3501 std::string json_string;
3502 llvm::raw_string_ostream os(json_string);
3503 os << params;
3504 os.flush();
3505
3506 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3507
3508 StringExtractorGDBRemote response;
3509 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3510 timeout) ==
3511 GDBRemoteCommunication::PacketResult::Success) {
3512 if (response.IsErrorResponse())
3513 return response.GetStatus().ToError();
3514 if (response.IsUnsupportedResponse())
3515 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3516 "jLLDBTraceStart is unsupported");
3517 if (response.IsOKResponse())
3518 return llvm::Error::success();
3519 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3520 "Invalid jLLDBTraceStart response");
3521 }
3522 LLDB_LOG(log, "failed to send packet: jLLDBTraceStart");
3523 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3524 "failed to send packet: jLLDBTraceStart '%s'",
3525 escaped_packet.GetData());
3526 }
3527
3528 llvm::Expected<std::string>
SendTraceGetState(llvm::StringRef type,std::chrono::seconds timeout)3529 GDBRemoteCommunicationClient::SendTraceGetState(llvm::StringRef type,
3530 std::chrono::seconds timeout) {
3531 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3532
3533 StreamGDBRemote escaped_packet;
3534 escaped_packet.PutCString("jLLDBTraceGetState:");
3535
3536 std::string json_string;
3537 llvm::raw_string_ostream os(json_string);
3538 os << toJSON(TraceGetStateRequest{type.str()});
3539 os.flush();
3540
3541 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3542
3543 StringExtractorGDBRemote response;
3544 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3545 timeout) ==
3546 GDBRemoteCommunication::PacketResult::Success) {
3547 if (response.IsErrorResponse())
3548 return response.GetStatus().ToError();
3549 if (response.IsUnsupportedResponse())
3550 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3551 "jLLDBTraceGetState is unsupported");
3552 return std::string(response.Peek());
3553 }
3554
3555 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState");
3556 return llvm::createStringError(
3557 llvm::inconvertibleErrorCode(),
3558 "failed to send packet: jLLDBTraceGetState '%s'",
3559 escaped_packet.GetData());
3560 }
3561
3562 llvm::Expected<std::vector<uint8_t>>
SendTraceGetBinaryData(const TraceGetBinaryDataRequest & request,std::chrono::seconds timeout)3563 GDBRemoteCommunicationClient::SendTraceGetBinaryData(
3564 const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {
3565 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
3566
3567 StreamGDBRemote escaped_packet;
3568 escaped_packet.PutCString("jLLDBTraceGetBinaryData:");
3569
3570 std::string json_string;
3571 llvm::raw_string_ostream os(json_string);
3572 os << toJSON(request);
3573 os.flush();
3574
3575 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
3576
3577 StringExtractorGDBRemote response;
3578 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
3579 timeout) ==
3580 GDBRemoteCommunication::PacketResult::Success) {
3581 if (response.IsErrorResponse())
3582 return response.GetStatus().ToError();
3583 if (response.IsUnsupportedResponse())
3584 return llvm::createStringError(llvm::inconvertibleErrorCode(),
3585 "jLLDBTraceGetBinaryData is unsupported");
3586 std::string data;
3587 response.GetEscapedBinaryData(data);
3588 return std::vector<uint8_t>(data.begin(), data.end());
3589 }
3590 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData");
3591 return llvm::createStringError(
3592 llvm::inconvertibleErrorCode(),
3593 "failed to send packet: jLLDBTraceGetBinaryData '%s'",
3594 escaped_packet.GetData());
3595 }
3596
GetQOffsets()3597 llvm::Optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() {
3598 StringExtractorGDBRemote response;
3599 if (SendPacketAndWaitForResponse("qOffsets", response) !=
3600 PacketResult::Success)
3601 return llvm::None;
3602 if (!response.IsNormalResponse())
3603 return llvm::None;
3604
3605 QOffsets result;
3606 llvm::StringRef ref = response.GetStringRef();
3607 const auto &GetOffset = [&] {
3608 addr_t offset;
3609 if (ref.consumeInteger(16, offset))
3610 return false;
3611 result.offsets.push_back(offset);
3612 return true;
3613 };
3614
3615 if (ref.consume_front("Text=")) {
3616 result.segments = false;
3617 if (!GetOffset())
3618 return llvm::None;
3619 if (!ref.consume_front(";Data=") || !GetOffset())
3620 return llvm::None;
3621 if (ref.empty())
3622 return result;
3623 if (ref.consume_front(";Bss=") && GetOffset() && ref.empty())
3624 return result;
3625 } else if (ref.consume_front("TextSeg=")) {
3626 result.segments = true;
3627 if (!GetOffset())
3628 return llvm::None;
3629 if (ref.empty())
3630 return result;
3631 if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty())
3632 return result;
3633 }
3634 return llvm::None;
3635 }
3636
GetModuleInfo(const FileSpec & module_file_spec,const lldb_private::ArchSpec & arch_spec,ModuleSpec & module_spec)3637 bool GDBRemoteCommunicationClient::GetModuleInfo(
3638 const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
3639 ModuleSpec &module_spec) {
3640 if (!m_supports_qModuleInfo)
3641 return false;
3642
3643 std::string module_path = module_file_spec.GetPath(false);
3644 if (module_path.empty())
3645 return false;
3646
3647 StreamString packet;
3648 packet.PutCString("qModuleInfo:");
3649 packet.PutStringAsRawHex8(module_path);
3650 packet.PutCString(";");
3651 const auto &triple = arch_spec.GetTriple().getTriple();
3652 packet.PutStringAsRawHex8(triple);
3653
3654 StringExtractorGDBRemote response;
3655 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
3656 PacketResult::Success)
3657 return false;
3658
3659 if (response.IsErrorResponse())
3660 return false;
3661
3662 if (response.IsUnsupportedResponse()) {
3663 m_supports_qModuleInfo = false;
3664 return false;
3665 }
3666
3667 llvm::StringRef name;
3668 llvm::StringRef value;
3669
3670 module_spec.Clear();
3671 module_spec.GetFileSpec() = module_file_spec;
3672
3673 while (response.GetNameColonValue(name, value)) {
3674 if (name == "uuid" || name == "md5") {
3675 StringExtractor extractor(value);
3676 std::string uuid;
3677 extractor.GetHexByteString(uuid);
3678 module_spec.GetUUID().SetFromStringRef(uuid);
3679 } else if (name == "triple") {
3680 StringExtractor extractor(value);
3681 std::string triple;
3682 extractor.GetHexByteString(triple);
3683 module_spec.GetArchitecture().SetTriple(triple.c_str());
3684 } else if (name == "file_offset") {
3685 uint64_t ival = 0;
3686 if (!value.getAsInteger(16, ival))
3687 module_spec.SetObjectOffset(ival);
3688 } else if (name == "file_size") {
3689 uint64_t ival = 0;
3690 if (!value.getAsInteger(16, ival))
3691 module_spec.SetObjectSize(ival);
3692 } else if (name == "file_path") {
3693 StringExtractor extractor(value);
3694 std::string path;
3695 extractor.GetHexByteString(path);
3696 module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
3697 }
3698 }
3699
3700 return true;
3701 }
3702
3703 static llvm::Optional<ModuleSpec>
ParseModuleSpec(StructuredData::Dictionary * dict)3704 ParseModuleSpec(StructuredData::Dictionary *dict) {
3705 ModuleSpec result;
3706 if (!dict)
3707 return llvm::None;
3708
3709 llvm::StringRef string;
3710 uint64_t integer;
3711
3712 if (!dict->GetValueForKeyAsString("uuid", string))
3713 return llvm::None;
3714 if (!result.GetUUID().SetFromStringRef(string))
3715 return llvm::None;
3716
3717 if (!dict->GetValueForKeyAsInteger("file_offset", integer))
3718 return llvm::None;
3719 result.SetObjectOffset(integer);
3720
3721 if (!dict->GetValueForKeyAsInteger("file_size", integer))
3722 return llvm::None;
3723 result.SetObjectSize(integer);
3724
3725 if (!dict->GetValueForKeyAsString("triple", string))
3726 return llvm::None;
3727 result.GetArchitecture().SetTriple(string);
3728
3729 if (!dict->GetValueForKeyAsString("file_path", string))
3730 return llvm::None;
3731 result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());
3732
3733 return result;
3734 }
3735
3736 llvm::Optional<std::vector<ModuleSpec>>
GetModulesInfo(llvm::ArrayRef<FileSpec> module_file_specs,const llvm::Triple & triple)3737 GDBRemoteCommunicationClient::GetModulesInfo(
3738 llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
3739 namespace json = llvm::json;
3740
3741 if (!m_supports_jModulesInfo)
3742 return llvm::None;
3743
3744 json::Array module_array;
3745 for (const FileSpec &module_file_spec : module_file_specs) {
3746 module_array.push_back(
3747 json::Object{{"file", module_file_spec.GetPath(false)},
3748 {"triple", triple.getTriple()}});
3749 }
3750 StreamString unescaped_payload;
3751 unescaped_payload.PutCString("jModulesInfo:");
3752 unescaped_payload.AsRawOstream() << std::move(module_array);
3753
3754 StreamGDBRemote payload;
3755 payload.PutEscapedBytes(unescaped_payload.GetString().data(),
3756 unescaped_payload.GetSize());
3757
3758 // Increase the timeout for jModulesInfo since this packet can take longer.
3759 ScopedTimeout timeout(*this, std::chrono::seconds(10));
3760
3761 StringExtractorGDBRemote response;
3762 if (SendPacketAndWaitForResponse(payload.GetString(), response) !=
3763 PacketResult::Success ||
3764 response.IsErrorResponse())
3765 return llvm::None;
3766
3767 if (response.IsUnsupportedResponse()) {
3768 m_supports_jModulesInfo = false;
3769 return llvm::None;
3770 }
3771
3772 StructuredData::ObjectSP response_object_sp =
3773 StructuredData::ParseJSON(std::string(response.GetStringRef()));
3774 if (!response_object_sp)
3775 return llvm::None;
3776
3777 StructuredData::Array *response_array = response_object_sp->GetAsArray();
3778 if (!response_array)
3779 return llvm::None;
3780
3781 std::vector<ModuleSpec> result;
3782 for (size_t i = 0; i < response_array->GetSize(); ++i) {
3783 if (llvm::Optional<ModuleSpec> module_spec = ParseModuleSpec(
3784 response_array->GetItemAtIndex(i)->GetAsDictionary()))
3785 result.push_back(*module_spec);
3786 }
3787
3788 return result;
3789 }
3790
3791 // query the target remote for extended information using the qXfer packet
3792 //
3793 // example: object='features', annex='target.xml', out=<xml output> return:
3794 // 'true' on success
3795 // 'false' on failure (err set)
ReadExtFeature(const lldb_private::ConstString object,const lldb_private::ConstString annex,std::string & out,lldb_private::Status & err)3796 bool GDBRemoteCommunicationClient::ReadExtFeature(
3797 const lldb_private::ConstString object,
3798 const lldb_private::ConstString annex, std::string &out,
3799 lldb_private::Status &err) {
3800
3801 std::stringstream output;
3802 StringExtractorGDBRemote chunk;
3803
3804 uint64_t size = GetRemoteMaxPacketSize();
3805 if (size == 0)
3806 size = 0x1000;
3807 size = size - 1; // Leave space for the 'm' or 'l' character in the response
3808 int offset = 0;
3809 bool active = true;
3810
3811 // loop until all data has been read
3812 while (active) {
3813
3814 // send query extended feature packet
3815 std::stringstream packet;
3816 packet << "qXfer:" << object.AsCString("")
3817 << ":read:" << annex.AsCString("") << ":" << std::hex << offset
3818 << "," << std::hex << size;
3819
3820 GDBRemoteCommunication::PacketResult res =
3821 SendPacketAndWaitForResponse(packet.str(), chunk);
3822
3823 if (res != GDBRemoteCommunication::PacketResult::Success) {
3824 err.SetErrorString("Error sending $qXfer packet");
3825 return false;
3826 }
3827
3828 const std::string &str = std::string(chunk.GetStringRef());
3829 if (str.length() == 0) {
3830 // should have some data in chunk
3831 err.SetErrorString("Empty response from $qXfer packet");
3832 return false;
3833 }
3834
3835 // check packet code
3836 switch (str[0]) {
3837 // last chunk
3838 case ('l'):
3839 active = false;
3840 LLVM_FALLTHROUGH;
3841
3842 // more chunks
3843 case ('m'):
3844 if (str.length() > 1)
3845 output << &str[1];
3846 offset += str.length() - 1;
3847 break;
3848
3849 // unknown chunk
3850 default:
3851 err.SetErrorString("Invalid continuation code from $qXfer packet");
3852 return false;
3853 }
3854 }
3855
3856 out = output.str();
3857 err.Success();
3858 return true;
3859 }
3860
3861 // Notify the target that gdb is prepared to serve symbol lookup requests.
3862 // packet: "qSymbol::"
3863 // reply:
3864 // OK The target does not need to look up any (more) symbols.
3865 // qSymbol:<sym_name> The target requests the value of symbol sym_name (hex
3866 // encoded).
3867 // LLDB may provide the value by sending another qSymbol
3868 // packet
3869 // in the form of"qSymbol:<sym_value>:<sym_name>".
3870 //
3871 // Three examples:
3872 //
3873 // lldb sends: qSymbol::
3874 // lldb receives: OK
3875 // Remote gdb stub does not need to know the addresses of any symbols, lldb
3876 // does not
3877 // need to ask again in this session.
3878 //
3879 // lldb sends: qSymbol::
3880 // lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3881 // lldb sends: qSymbol::64697370617463685f71756575655f6f666673657473
3882 // lldb receives: OK
3883 // Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does
3884 // not know
3885 // the address at this time. lldb needs to send qSymbol:: again when it has
3886 // more
3887 // solibs loaded.
3888 //
3889 // lldb sends: qSymbol::
3890 // lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
3891 // lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
3892 // lldb receives: OK
3893 // Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says
3894 // that it
3895 // is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it
3896 // does not
3897 // need any more symbols. lldb does not need to ask again in this session.
3898
ServeSymbolLookups(lldb_private::Process * process)3899 void GDBRemoteCommunicationClient::ServeSymbolLookups(
3900 lldb_private::Process *process) {
3901 // Set to true once we've resolved a symbol to an address for the remote
3902 // stub. If we get an 'OK' response after this, the remote stub doesn't need
3903 // any more symbols and we can stop asking.
3904 bool symbol_response_provided = false;
3905
3906 // Is this the initial qSymbol:: packet?
3907 bool first_qsymbol_query = true;
3908
3909 if (m_supports_qSymbol && !m_qSymbol_requests_done) {
3910 Lock lock(*this);
3911 if (lock) {
3912 StreamString packet;
3913 packet.PutCString("qSymbol::");
3914 StringExtractorGDBRemote response;
3915 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
3916 PacketResult::Success) {
3917 if (response.IsOKResponse()) {
3918 if (symbol_response_provided || first_qsymbol_query) {
3919 m_qSymbol_requests_done = true;
3920 }
3921
3922 // We are done serving symbols requests
3923 return;
3924 }
3925 first_qsymbol_query = false;
3926
3927 if (response.IsUnsupportedResponse()) {
3928 // qSymbol is not supported by the current GDB server we are
3929 // connected to
3930 m_supports_qSymbol = false;
3931 return;
3932 } else {
3933 llvm::StringRef response_str(response.GetStringRef());
3934 if (response_str.startswith("qSymbol:")) {
3935 response.SetFilePos(strlen("qSymbol:"));
3936 std::string symbol_name;
3937 if (response.GetHexByteString(symbol_name)) {
3938 if (symbol_name.empty())
3939 return;
3940
3941 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
3942 lldb_private::SymbolContextList sc_list;
3943 process->GetTarget().GetImages().FindSymbolsWithNameAndType(
3944 ConstString(symbol_name), eSymbolTypeAny, sc_list);
3945 if (!sc_list.IsEmpty()) {
3946 const size_t num_scs = sc_list.GetSize();
3947 for (size_t sc_idx = 0;
3948 sc_idx < num_scs &&
3949 symbol_load_addr == LLDB_INVALID_ADDRESS;
3950 ++sc_idx) {
3951 SymbolContext sc;
3952 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
3953 if (sc.symbol) {
3954 switch (sc.symbol->GetType()) {
3955 case eSymbolTypeInvalid:
3956 case eSymbolTypeAbsolute:
3957 case eSymbolTypeUndefined:
3958 case eSymbolTypeSourceFile:
3959 case eSymbolTypeHeaderFile:
3960 case eSymbolTypeObjectFile:
3961 case eSymbolTypeCommonBlock:
3962 case eSymbolTypeBlock:
3963 case eSymbolTypeLocal:
3964 case eSymbolTypeParam:
3965 case eSymbolTypeVariable:
3966 case eSymbolTypeVariableType:
3967 case eSymbolTypeLineEntry:
3968 case eSymbolTypeLineHeader:
3969 case eSymbolTypeScopeBegin:
3970 case eSymbolTypeScopeEnd:
3971 case eSymbolTypeAdditional:
3972 case eSymbolTypeCompiler:
3973 case eSymbolTypeInstrumentation:
3974 case eSymbolTypeTrampoline:
3975 break;
3976
3977 case eSymbolTypeCode:
3978 case eSymbolTypeResolver:
3979 case eSymbolTypeData:
3980 case eSymbolTypeRuntime:
3981 case eSymbolTypeException:
3982 case eSymbolTypeObjCClass:
3983 case eSymbolTypeObjCMetaClass:
3984 case eSymbolTypeObjCIVar:
3985 case eSymbolTypeReExported:
3986 symbol_load_addr =
3987 sc.symbol->GetLoadAddress(&process->GetTarget());
3988 break;
3989 }
3990 }
3991 }
3992 }
3993 }
3994 // This is the normal path where our symbol lookup was successful
3995 // and we want to send a packet with the new symbol value and see
3996 // if another lookup needs to be done.
3997
3998 // Change "packet" to contain the requested symbol value and name
3999 packet.Clear();
4000 packet.PutCString("qSymbol:");
4001 if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
4002 packet.Printf("%" PRIx64, symbol_load_addr);
4003 symbol_response_provided = true;
4004 } else {
4005 symbol_response_provided = false;
4006 }
4007 packet.PutCString(":");
4008 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
4009 continue; // go back to the while loop and send "packet" and wait
4010 // for another response
4011 }
4012 }
4013 }
4014 }
4015 // If we make it here, the symbol request packet response wasn't valid or
4016 // our symbol lookup failed so we must abort
4017 return;
4018
4019 } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
4020 GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
4021 LLDB_LOGF(log,
4022 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
4023 __FUNCTION__);
4024 }
4025 }
4026 }
4027
4028 StructuredData::Array *
GetSupportedStructuredDataPlugins()4029 GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
4030 if (!m_supported_async_json_packets_is_valid) {
4031 // Query the server for the array of supported asynchronous JSON packets.
4032 m_supported_async_json_packets_is_valid = true;
4033
4034 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
4035
4036 // Poll it now.
4037 StringExtractorGDBRemote response;
4038 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) ==
4039 PacketResult::Success) {
4040 m_supported_async_json_packets_sp =
4041 StructuredData::ParseJSON(std::string(response.GetStringRef()));
4042 if (m_supported_async_json_packets_sp &&
4043 !m_supported_async_json_packets_sp->GetAsArray()) {
4044 // We were returned something other than a JSON array. This is
4045 // invalid. Clear it out.
4046 LLDB_LOGF(log,
4047 "GDBRemoteCommunicationClient::%s(): "
4048 "QSupportedAsyncJSONPackets returned invalid "
4049 "result: %s",
4050 __FUNCTION__, response.GetStringRef().data());
4051 m_supported_async_json_packets_sp.reset();
4052 }
4053 } else {
4054 LLDB_LOGF(log,
4055 "GDBRemoteCommunicationClient::%s(): "
4056 "QSupportedAsyncJSONPackets unsupported",
4057 __FUNCTION__);
4058 }
4059
4060 if (log && m_supported_async_json_packets_sp) {
4061 StreamString stream;
4062 m_supported_async_json_packets_sp->Dump(stream);
4063 LLDB_LOGF(log,
4064 "GDBRemoteCommunicationClient::%s(): supported async "
4065 "JSON packets: %s",
4066 __FUNCTION__, stream.GetData());
4067 }
4068 }
4069
4070 return m_supported_async_json_packets_sp
4071 ? m_supported_async_json_packets_sp->GetAsArray()
4072 : nullptr;
4073 }
4074
SendSignalsToIgnore(llvm::ArrayRef<int32_t> signals)4075 Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
4076 llvm::ArrayRef<int32_t> signals) {
4077 // Format packet:
4078 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
4079 auto range = llvm::make_range(signals.begin(), signals.end());
4080 std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
4081
4082 StringExtractorGDBRemote response;
4083 auto send_status = SendPacketAndWaitForResponse(packet, response);
4084
4085 if (send_status != GDBRemoteCommunication::PacketResult::Success)
4086 return Status("Sending QPassSignals packet failed");
4087
4088 if (response.IsOKResponse()) {
4089 return Status();
4090 } else {
4091 return Status("Unknown error happened during sending QPassSignals packet.");
4092 }
4093 }
4094
ConfigureRemoteStructuredData(ConstString type_name,const StructuredData::ObjectSP & config_sp)4095 Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
4096 ConstString type_name, const StructuredData::ObjectSP &config_sp) {
4097 Status error;
4098
4099 if (type_name.GetLength() == 0) {
4100 error.SetErrorString("invalid type_name argument");
4101 return error;
4102 }
4103
4104 // Build command: Configure{type_name}: serialized config data.
4105 StreamGDBRemote stream;
4106 stream.PutCString("QConfigure");
4107 stream.PutCString(type_name.GetStringRef());
4108 stream.PutChar(':');
4109 if (config_sp) {
4110 // Gather the plain-text version of the configuration data.
4111 StreamString unescaped_stream;
4112 config_sp->Dump(unescaped_stream);
4113 unescaped_stream.Flush();
4114
4115 // Add it to the stream in escaped fashion.
4116 stream.PutEscapedBytes(unescaped_stream.GetString().data(),
4117 unescaped_stream.GetSize());
4118 }
4119 stream.Flush();
4120
4121 // Send the packet.
4122 StringExtractorGDBRemote response;
4123 auto result = SendPacketAndWaitForResponse(stream.GetString(), response);
4124 if (result == PacketResult::Success) {
4125 // We failed if the config result comes back other than OK.
4126 if (strcmp(response.GetStringRef().data(), "OK") == 0) {
4127 // Okay!
4128 error.Clear();
4129 } else {
4130 error.SetErrorStringWithFormat("configuring StructuredData feature "
4131 "%s failed with error %s",
4132 type_name.AsCString(),
4133 response.GetStringRef().data());
4134 }
4135 } else {
4136 // Can we get more data here on the failure?
4137 error.SetErrorStringWithFormat("configuring StructuredData feature %s "
4138 "failed when sending packet: "
4139 "PacketResult=%d",
4140 type_name.AsCString(), (int)result);
4141 }
4142 return error;
4143 }
4144
OnRunPacketSent(bool first)4145 void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
4146 GDBRemoteClientBase::OnRunPacketSent(first);
4147 m_curr_tid = LLDB_INVALID_THREAD_ID;
4148 }
4149