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