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