Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
39642 views
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
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
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
80
GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
81
if (IsConnected())
82
Disconnect();
83
}
84
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
124
bool GDBRemoteCommunicationClient::GetEchoSupported() {
125
if (m_supports_qEcho == eLazyBoolCalculate) {
126
GetRemoteQSupported();
127
}
128
return m_supports_qEcho == eLazyBoolYes;
129
}
130
131
bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
132
if (m_supports_QPassSignals == eLazyBoolCalculate) {
133
GetRemoteQSupported();
134
}
135
return m_supports_QPassSignals == eLazyBoolYes;
136
}
137
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
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
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
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
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
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
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
187
bool GDBRemoteCommunicationClient::GetMultiprocessSupported() {
188
if (m_supports_memory_tagging == eLazyBoolCalculate)
189
GetRemoteQSupported();
190
return m_supports_multiprocess == eLazyBoolYes;
191
}
192
193
uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
194
if (m_max_packet_size == 0) {
195
GetRemoteQSupported();
196
}
197
return m_max_packet_size;
198
}
199
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
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
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
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
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
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
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
}
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
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.
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
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
551
bool GDBRemoteCommunicationClient::GetSaveCoreSupported() const {
552
return m_supports_qSaveCore == eLazyBoolYes;
553
}
554
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
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
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
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
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
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
644
bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {
645
if (m_supports_memory_tagging == eLazyBoolCalculate) {
646
GetRemoteQSupported();
647
}
648
return m_supports_memory_tagging == eLazyBoolYes;
649
}
650
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
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
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
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
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
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
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
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
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
967
llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
968
GetHostInfo();
969
return m_os_version;
970
}
971
972
llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {
973
GetHostInfo();
974
return m_maccatalyst_version;
975
}
976
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>
986
GDBRemoteCommunicationClient::GetOSKernelDescription() {
987
if (GetHostInfo()) {
988
if (!m_os_kernel.empty())
989
return m_os_kernel;
990
}
991
return std::nullopt;
992
}
993
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
1005
ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
1006
if (GetHostInfo())
1007
return m_host_arch;
1008
return ArchSpec();
1009
}
1010
1011
const lldb_private::ArchSpec &
1012
GDBRemoteCommunicationClient::GetProcessArchitecture() {
1013
if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
1014
GetCurrentProcessInfo();
1015
return m_process_arch;
1016
}
1017
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>
1036
GDBRemoteCommunicationClient::GetProcessStandaloneBinaries() {
1037
if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
1038
GetCurrentProcessInfo();
1039
return m_binary_addresses;
1040
}
1041
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
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
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
1158
uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
1159
if (GetGDBServerVersion())
1160
return m_gdb_server_version;
1161
return 0;
1162
}
1163
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
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
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
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 &
1425
GDBRemoteCommunicationClient::GetHostArchitecture() {
1426
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1427
GetHostInfo();
1428
return m_host_arch;
1429
}
1430
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
1444
seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
1445
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1446
GetHostInfo();
1447
return m_default_packet_timeout;
1448
}
1449
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
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
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
1549
Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
1550
lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_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
1713
Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
1714
lldb::addr_t addr, MemoryRegionInfo &region) {
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
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
[&region](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
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
1844
GDBRemoteCommunicationClient::GetSupportedWatchpointTypes() {
1845
return m_watchpoint_types;
1846
}
1847
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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>
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
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
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
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
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
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
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
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
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
2780
bool GDBRemoteCommunicationClient::GetStopReply(
2781
StringExtractorGDBRemote &response) {
2782
if (SendPacketAndWaitForResponse("?", response) == PacketResult::Success)
2783
return response.IsNormalResponse();
2784
return false;
2785
}
2786
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
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>>
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
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
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
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
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
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
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
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
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
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>
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>
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.
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
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
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
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
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
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
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.
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
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
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
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
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
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
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
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
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
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>
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
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
3691
GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value &params,
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>
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>>
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
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
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>
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>>
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>
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
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 *
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
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
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
4321
void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
4322
GDBRemoteClientBase::OnRunPacketSent(first);
4323
m_curr_tid = LLDB_INVALID_THREAD_ID;
4324
}
4325
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
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
4355