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/GDBRemoteCommunicationServerCommon.cpp
39642 views
1
//===-- GDBRemoteCommunicationServerCommon.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 "GDBRemoteCommunicationServerCommon.h"
10
11
#include <cerrno>
12
13
#ifdef __APPLE__
14
#include <TargetConditionals.h>
15
#endif
16
17
#include <chrono>
18
#include <cstring>
19
#include <optional>
20
21
#include "lldb/Core/ModuleSpec.h"
22
#include "lldb/Host/Config.h"
23
#include "lldb/Host/File.h"
24
#include "lldb/Host/FileAction.h"
25
#include "lldb/Host/FileSystem.h"
26
#include "lldb/Host/Host.h"
27
#include "lldb/Host/HostInfo.h"
28
#include "lldb/Host/SafeMachO.h"
29
#include "lldb/Interpreter/OptionArgParser.h"
30
#include "lldb/Symbol/ObjectFile.h"
31
#include "lldb/Target/Platform.h"
32
#include "lldb/Utility/Endian.h"
33
#include "lldb/Utility/GDBRemote.h"
34
#include "lldb/Utility/LLDBLog.h"
35
#include "lldb/Utility/Log.h"
36
#include "lldb/Utility/StreamString.h"
37
#include "lldb/Utility/StructuredData.h"
38
#include "llvm/ADT/StringSwitch.h"
39
#include "llvm/Support/JSON.h"
40
#include "llvm/TargetParser/Triple.h"
41
42
#include "ProcessGDBRemoteLog.h"
43
#include "lldb/Utility/StringExtractorGDBRemote.h"
44
45
#ifdef __ANDROID__
46
#include "lldb/Host/android/HostInfoAndroid.h"
47
#include "lldb/Host/common/ZipFileResolver.h"
48
#endif
49
50
using namespace lldb;
51
using namespace lldb_private::process_gdb_remote;
52
using namespace lldb_private;
53
54
#ifdef __ANDROID__
55
const static uint32_t g_default_packet_timeout_sec = 20; // seconds
56
#else
57
const static uint32_t g_default_packet_timeout_sec = 0; // not specified
58
#endif
59
60
// GDBRemoteCommunicationServerCommon constructor
61
GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon()
62
: GDBRemoteCommunicationServer(), m_process_launch_info(),
63
m_process_launch_error(), m_proc_infos(), m_proc_infos_index(0) {
64
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
65
&GDBRemoteCommunicationServerCommon::Handle_A);
66
RegisterMemberFunctionHandler(
67
StringExtractorGDBRemote::eServerPacketType_QEnvironment,
68
&GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
69
RegisterMemberFunctionHandler(
70
StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
71
&GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
72
RegisterMemberFunctionHandler(
73
StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,
74
&GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);
75
RegisterMemberFunctionHandler(
76
StringExtractorGDBRemote::eServerPacketType_qGroupName,
77
&GDBRemoteCommunicationServerCommon::Handle_qGroupName);
78
RegisterMemberFunctionHandler(
79
StringExtractorGDBRemote::eServerPacketType_qHostInfo,
80
&GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
81
RegisterMemberFunctionHandler(
82
StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
83
&GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
84
RegisterMemberFunctionHandler(
85
StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
86
&GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
87
RegisterMemberFunctionHandler(
88
StringExtractorGDBRemote::eServerPacketType_qEcho,
89
&GDBRemoteCommunicationServerCommon::Handle_qEcho);
90
RegisterMemberFunctionHandler(
91
StringExtractorGDBRemote::eServerPacketType_qModuleInfo,
92
&GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);
93
RegisterMemberFunctionHandler(
94
StringExtractorGDBRemote::eServerPacketType_jModulesInfo,
95
&GDBRemoteCommunicationServerCommon::Handle_jModulesInfo);
96
RegisterMemberFunctionHandler(
97
StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,
98
&GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);
99
RegisterMemberFunctionHandler(
100
StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,
101
&GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);
102
RegisterMemberFunctionHandler(
103
StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,
104
&GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);
105
RegisterMemberFunctionHandler(
106
StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,
107
&GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);
108
RegisterMemberFunctionHandler(
109
StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,
110
&GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);
111
RegisterMemberFunctionHandler(
112
StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,
113
&GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);
114
RegisterMemberFunctionHandler(
115
StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,
116
&GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);
117
RegisterMemberFunctionHandler(
118
StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,
119
&GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);
120
RegisterMemberFunctionHandler(
121
StringExtractorGDBRemote::eServerPacketType_qSpeedTest,
122
&GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);
123
RegisterMemberFunctionHandler(
124
StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,
125
&GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);
126
RegisterMemberFunctionHandler(
127
StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,
128
&GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);
129
RegisterMemberFunctionHandler(
130
StringExtractorGDBRemote::eServerPacketType_qSupported,
131
&GDBRemoteCommunicationServerCommon::Handle_qSupported);
132
RegisterMemberFunctionHandler(
133
StringExtractorGDBRemote::eServerPacketType_qUserName,
134
&GDBRemoteCommunicationServerCommon::Handle_qUserName);
135
RegisterMemberFunctionHandler(
136
StringExtractorGDBRemote::eServerPacketType_vFile_close,
137
&GDBRemoteCommunicationServerCommon::Handle_vFile_Close);
138
RegisterMemberFunctionHandler(
139
StringExtractorGDBRemote::eServerPacketType_vFile_exists,
140
&GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);
141
RegisterMemberFunctionHandler(
142
StringExtractorGDBRemote::eServerPacketType_vFile_md5,
143
&GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);
144
RegisterMemberFunctionHandler(
145
StringExtractorGDBRemote::eServerPacketType_vFile_mode,
146
&GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);
147
RegisterMemberFunctionHandler(
148
StringExtractorGDBRemote::eServerPacketType_vFile_open,
149
&GDBRemoteCommunicationServerCommon::Handle_vFile_Open);
150
RegisterMemberFunctionHandler(
151
StringExtractorGDBRemote::eServerPacketType_vFile_pread,
152
&GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);
153
RegisterMemberFunctionHandler(
154
StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,
155
&GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);
156
RegisterMemberFunctionHandler(
157
StringExtractorGDBRemote::eServerPacketType_vFile_size,
158
&GDBRemoteCommunicationServerCommon::Handle_vFile_Size);
159
RegisterMemberFunctionHandler(
160
StringExtractorGDBRemote::eServerPacketType_vFile_fstat,
161
&GDBRemoteCommunicationServerCommon::Handle_vFile_FStat);
162
RegisterMemberFunctionHandler(
163
StringExtractorGDBRemote::eServerPacketType_vFile_stat,
164
&GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);
165
RegisterMemberFunctionHandler(
166
StringExtractorGDBRemote::eServerPacketType_vFile_symlink,
167
&GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);
168
RegisterMemberFunctionHandler(
169
StringExtractorGDBRemote::eServerPacketType_vFile_unlink,
170
&GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
171
}
172
173
// Destructor
174
GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() =
175
default;
176
177
GDBRemoteCommunication::PacketResult
178
GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
179
StringExtractorGDBRemote &packet) {
180
StreamString response;
181
182
// $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
183
184
ArchSpec host_arch(HostInfo::GetArchitecture());
185
const llvm::Triple &host_triple = host_arch.GetTriple();
186
response.PutCString("triple:");
187
response.PutStringAsRawHex8(host_triple.getTriple());
188
response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize());
189
190
llvm::StringRef distribution_id = HostInfo::GetDistributionId();
191
if (!distribution_id.empty()) {
192
response.PutCString("distribution_id:");
193
response.PutStringAsRawHex8(distribution_id);
194
response.PutCString(";");
195
}
196
197
#if defined(__APPLE__)
198
// For parity with debugserver, we'll include the vendor key.
199
response.PutCString("vendor:apple;");
200
201
// Send out MachO info.
202
uint32_t cpu = host_arch.GetMachOCPUType();
203
uint32_t sub = host_arch.GetMachOCPUSubType();
204
if (cpu != LLDB_INVALID_CPUTYPE)
205
response.Printf("cputype:%u;", cpu);
206
if (sub != LLDB_INVALID_CPUTYPE)
207
response.Printf("cpusubtype:%u;", sub);
208
209
if (cpu == llvm::MachO::CPU_TYPE_ARM || cpu == llvm::MachO::CPU_TYPE_ARM64) {
210
// Indicate the OS type.
211
#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
212
response.PutCString("ostype:tvos;");
213
#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
214
response.PutCString("ostype:watchos;");
215
#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
216
response.PutCString("ostype:bridgeos;");
217
#else
218
response.PutCString("ostype:ios;");
219
#endif
220
221
// On arm, we use "synchronous" watchpoints which means the exception is
222
// delivered before the instruction executes.
223
response.PutCString("watchpoint_exceptions_received:before;");
224
} else {
225
response.PutCString("ostype:macosx;");
226
response.Printf("watchpoint_exceptions_received:after;");
227
}
228
229
#else
230
if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
231
host_arch.GetMachine() == llvm::Triple::aarch64_32 ||
232
host_arch.GetMachine() == llvm::Triple::aarch64_be ||
233
host_arch.GetMachine() == llvm::Triple::arm ||
234
host_arch.GetMachine() == llvm::Triple::armeb || host_arch.IsMIPS())
235
response.Printf("watchpoint_exceptions_received:before;");
236
else
237
response.Printf("watchpoint_exceptions_received:after;");
238
#endif
239
240
switch (endian::InlHostByteOrder()) {
241
case eByteOrderBig:
242
response.PutCString("endian:big;");
243
break;
244
case eByteOrderLittle:
245
response.PutCString("endian:little;");
246
break;
247
case eByteOrderPDP:
248
response.PutCString("endian:pdp;");
249
break;
250
default:
251
response.PutCString("endian:unknown;");
252
break;
253
}
254
255
llvm::VersionTuple version = HostInfo::GetOSVersion();
256
if (!version.empty()) {
257
response.Format("os_version:{0}", version.getAsString());
258
response.PutChar(';');
259
}
260
261
#if defined(__APPLE__)
262
llvm::VersionTuple maccatalyst_version = HostInfo::GetMacCatalystVersion();
263
if (!maccatalyst_version.empty()) {
264
response.Format("maccatalyst_version:{0}",
265
maccatalyst_version.getAsString());
266
response.PutChar(';');
267
}
268
#endif
269
270
if (std::optional<std::string> s = HostInfo::GetOSBuildString()) {
271
response.PutCString("os_build:");
272
response.PutStringAsRawHex8(*s);
273
response.PutChar(';');
274
}
275
if (std::optional<std::string> s = HostInfo::GetOSKernelDescription()) {
276
response.PutCString("os_kernel:");
277
response.PutStringAsRawHex8(*s);
278
response.PutChar(';');
279
}
280
281
std::string s;
282
#if defined(__APPLE__)
283
284
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
285
// For iOS devices, we are connected through a USB Mux so we never pretend to
286
// actually have a hostname as far as the remote lldb that is connecting to
287
// this lldb-platform is concerned
288
response.PutCString("hostname:");
289
response.PutStringAsRawHex8("127.0.0.1");
290
response.PutChar(';');
291
#else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
292
if (HostInfo::GetHostname(s)) {
293
response.PutCString("hostname:");
294
response.PutStringAsRawHex8(s);
295
response.PutChar(';');
296
}
297
#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
298
299
#else // #if defined(__APPLE__)
300
if (HostInfo::GetHostname(s)) {
301
response.PutCString("hostname:");
302
response.PutStringAsRawHex8(s);
303
response.PutChar(';');
304
}
305
#endif // #if defined(__APPLE__)
306
// coverity[unsigned_compare]
307
if (g_default_packet_timeout_sec > 0)
308
response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec);
309
310
return SendPacketNoLock(response.GetString());
311
}
312
313
GDBRemoteCommunication::PacketResult
314
GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID(
315
StringExtractorGDBRemote &packet) {
316
// Packet format: "qProcessInfoPID:%i" where %i is the pid
317
packet.SetFilePos(::strlen("qProcessInfoPID:"));
318
lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID);
319
if (pid != LLDB_INVALID_PROCESS_ID) {
320
ProcessInstanceInfo proc_info;
321
if (Host::GetProcessInfo(pid, proc_info)) {
322
StreamString response;
323
CreateProcessInfoResponse(proc_info, response);
324
return SendPacketNoLock(response.GetString());
325
}
326
}
327
return SendErrorResponse(1);
328
}
329
330
GDBRemoteCommunication::PacketResult
331
GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
332
StringExtractorGDBRemote &packet) {
333
m_proc_infos_index = 0;
334
m_proc_infos.clear();
335
336
ProcessInstanceInfoMatch match_info;
337
packet.SetFilePos(::strlen("qfProcessInfo"));
338
if (packet.GetChar() == ':') {
339
llvm::StringRef key;
340
llvm::StringRef value;
341
while (packet.GetNameColonValue(key, value)) {
342
bool success = true;
343
if (key == "name") {
344
StringExtractor extractor(value);
345
std::string file;
346
extractor.GetHexByteString(file);
347
match_info.GetProcessInfo().GetExecutableFile().SetFile(
348
file, FileSpec::Style::native);
349
} else if (key == "name_match") {
350
NameMatch name_match = llvm::StringSwitch<NameMatch>(value)
351
.Case("equals", NameMatch::Equals)
352
.Case("starts_with", NameMatch::StartsWith)
353
.Case("ends_with", NameMatch::EndsWith)
354
.Case("contains", NameMatch::Contains)
355
.Case("regex", NameMatch::RegularExpression)
356
.Default(NameMatch::Ignore);
357
match_info.SetNameMatchType(name_match);
358
if (name_match == NameMatch::Ignore)
359
return SendErrorResponse(2);
360
} else if (key == "pid") {
361
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
362
if (value.getAsInteger(0, pid))
363
return SendErrorResponse(2);
364
match_info.GetProcessInfo().SetProcessID(pid);
365
} else if (key == "parent_pid") {
366
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
367
if (value.getAsInteger(0, pid))
368
return SendErrorResponse(2);
369
match_info.GetProcessInfo().SetParentProcessID(pid);
370
} else if (key == "uid") {
371
uint32_t uid = UINT32_MAX;
372
if (value.getAsInteger(0, uid))
373
return SendErrorResponse(2);
374
match_info.GetProcessInfo().SetUserID(uid);
375
} else if (key == "gid") {
376
uint32_t gid = UINT32_MAX;
377
if (value.getAsInteger(0, gid))
378
return SendErrorResponse(2);
379
match_info.GetProcessInfo().SetGroupID(gid);
380
} else if (key == "euid") {
381
uint32_t uid = UINT32_MAX;
382
if (value.getAsInteger(0, uid))
383
return SendErrorResponse(2);
384
match_info.GetProcessInfo().SetEffectiveUserID(uid);
385
} else if (key == "egid") {
386
uint32_t gid = UINT32_MAX;
387
if (value.getAsInteger(0, gid))
388
return SendErrorResponse(2);
389
match_info.GetProcessInfo().SetEffectiveGroupID(gid);
390
} else if (key == "all_users") {
391
match_info.SetMatchAllUsers(
392
OptionArgParser::ToBoolean(value, false, &success));
393
} else if (key == "triple") {
394
match_info.GetProcessInfo().GetArchitecture() =
395
HostInfo::GetAugmentedArchSpec(value);
396
} else {
397
success = false;
398
}
399
400
if (!success)
401
return SendErrorResponse(2);
402
}
403
}
404
405
if (Host::FindProcesses(match_info, m_proc_infos)) {
406
// We found something, return the first item by calling the get subsequent
407
// process info packet handler...
408
return Handle_qsProcessInfo(packet);
409
}
410
return SendErrorResponse(3);
411
}
412
413
GDBRemoteCommunication::PacketResult
414
GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(
415
StringExtractorGDBRemote &packet) {
416
if (m_proc_infos_index < m_proc_infos.size()) {
417
StreamString response;
418
CreateProcessInfoResponse(m_proc_infos[m_proc_infos_index], response);
419
++m_proc_infos_index;
420
return SendPacketNoLock(response.GetString());
421
}
422
return SendErrorResponse(4);
423
}
424
425
GDBRemoteCommunication::PacketResult
426
GDBRemoteCommunicationServerCommon::Handle_qUserName(
427
StringExtractorGDBRemote &packet) {
428
#if LLDB_ENABLE_POSIX
429
Log *log = GetLog(LLDBLog::Process);
430
LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
431
432
// Packet format: "qUserName:%i" where %i is the uid
433
packet.SetFilePos(::strlen("qUserName:"));
434
uint32_t uid = packet.GetU32(UINT32_MAX);
435
if (uid != UINT32_MAX) {
436
if (std::optional<llvm::StringRef> name =
437
HostInfo::GetUserIDResolver().GetUserName(uid)) {
438
StreamString response;
439
response.PutStringAsRawHex8(*name);
440
return SendPacketNoLock(response.GetString());
441
}
442
}
443
LLDB_LOGF(log, "GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
444
#endif
445
return SendErrorResponse(5);
446
}
447
448
GDBRemoteCommunication::PacketResult
449
GDBRemoteCommunicationServerCommon::Handle_qGroupName(
450
StringExtractorGDBRemote &packet) {
451
#if LLDB_ENABLE_POSIX
452
// Packet format: "qGroupName:%i" where %i is the gid
453
packet.SetFilePos(::strlen("qGroupName:"));
454
uint32_t gid = packet.GetU32(UINT32_MAX);
455
if (gid != UINT32_MAX) {
456
if (std::optional<llvm::StringRef> name =
457
HostInfo::GetUserIDResolver().GetGroupName(gid)) {
458
StreamString response;
459
response.PutStringAsRawHex8(*name);
460
return SendPacketNoLock(response.GetString());
461
}
462
}
463
#endif
464
return SendErrorResponse(6);
465
}
466
467
GDBRemoteCommunication::PacketResult
468
GDBRemoteCommunicationServerCommon::Handle_qSpeedTest(
469
StringExtractorGDBRemote &packet) {
470
packet.SetFilePos(::strlen("qSpeedTest:"));
471
472
llvm::StringRef key;
473
llvm::StringRef value;
474
bool success = packet.GetNameColonValue(key, value);
475
if (success && key == "response_size") {
476
uint32_t response_size = 0;
477
if (!value.getAsInteger(0, response_size)) {
478
if (response_size == 0)
479
return SendOKResponse();
480
StreamString response;
481
uint32_t bytes_left = response_size;
482
response.PutCString("data:");
483
while (bytes_left > 0) {
484
if (bytes_left >= 26) {
485
response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
486
bytes_left -= 26;
487
} else {
488
response.Printf("%*.*s;", bytes_left, bytes_left,
489
"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
490
bytes_left = 0;
491
}
492
}
493
return SendPacketNoLock(response.GetString());
494
}
495
}
496
return SendErrorResponse(7);
497
}
498
499
GDBRemoteCommunication::PacketResult
500
GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
501
StringExtractorGDBRemote &packet) {
502
packet.SetFilePos(::strlen("vFile:open:"));
503
std::string path;
504
packet.GetHexByteStringTerminatedBy(path, ',');
505
if (!path.empty()) {
506
if (packet.GetChar() == ',') {
507
auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0));
508
if (packet.GetChar() == ',') {
509
mode_t mode = packet.GetHexMaxU32(false, 0600);
510
FileSpec path_spec(path);
511
FileSystem::Instance().Resolve(path_spec);
512
// Do not close fd.
513
auto file = FileSystem::Instance().Open(path_spec, flags, mode, false);
514
515
StreamString response;
516
response.PutChar('F');
517
518
int descriptor = File::kInvalidDescriptor;
519
if (file) {
520
descriptor = file.get()->GetDescriptor();
521
response.Printf("%x", descriptor);
522
} else {
523
response.PutCString("-1");
524
std::error_code code = errorToErrorCode(file.takeError());
525
if (code.category() == std::system_category()) {
526
response.Printf(",%x", code.value());
527
}
528
}
529
530
return SendPacketNoLock(response.GetString());
531
}
532
}
533
}
534
return SendErrorResponse(18);
535
}
536
537
static GDBErrno system_errno_to_gdb(int err) {
538
switch (err) {
539
#define HANDLE_ERRNO(name, value) \
540
case name: \
541
return GDB_##name;
542
#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
543
default:
544
return GDB_EUNKNOWN;
545
}
546
}
547
548
GDBRemoteCommunication::PacketResult
549
GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
550
StringExtractorGDBRemote &packet) {
551
packet.SetFilePos(::strlen("vFile:close:"));
552
int fd = packet.GetS32(-1, 16);
553
int err = -1;
554
int save_errno = 0;
555
if (fd >= 0) {
556
NativeFile file(fd, File::OpenOptions(0), true);
557
Status error = file.Close();
558
err = 0;
559
save_errno = error.GetError();
560
} else {
561
save_errno = EINVAL;
562
}
563
StreamString response;
564
response.PutChar('F');
565
response.Printf("%x", err);
566
if (save_errno)
567
response.Printf(",%x", system_errno_to_gdb(save_errno));
568
return SendPacketNoLock(response.GetString());
569
}
570
571
GDBRemoteCommunication::PacketResult
572
GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
573
StringExtractorGDBRemote &packet) {
574
StreamGDBRemote response;
575
packet.SetFilePos(::strlen("vFile:pread:"));
576
int fd = packet.GetS32(-1, 16);
577
if (packet.GetChar() == ',') {
578
size_t count = packet.GetHexMaxU64(false, SIZE_MAX);
579
if (packet.GetChar() == ',') {
580
off_t offset = packet.GetHexMaxU32(false, UINT32_MAX);
581
if (count == SIZE_MAX) {
582
response.Printf("F-1:%x", EINVAL);
583
return SendPacketNoLock(response.GetString());
584
}
585
586
std::string buffer(count, 0);
587
NativeFile file(fd, File::eOpenOptionReadOnly, false);
588
Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset);
589
const int save_errno = error.GetError();
590
response.PutChar('F');
591
if (error.Success()) {
592
response.Printf("%zx", count);
593
response.PutChar(';');
594
response.PutEscapedBytes(&buffer[0], count);
595
} else {
596
response.PutCString("-1");
597
if (save_errno)
598
response.Printf(",%x", system_errno_to_gdb(save_errno));
599
}
600
return SendPacketNoLock(response.GetString());
601
}
602
}
603
return SendErrorResponse(21);
604
}
605
606
GDBRemoteCommunication::PacketResult
607
GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
608
StringExtractorGDBRemote &packet) {
609
packet.SetFilePos(::strlen("vFile:pwrite:"));
610
611
StreamGDBRemote response;
612
response.PutChar('F');
613
614
int fd = packet.GetS32(-1, 16);
615
if (packet.GetChar() == ',') {
616
off_t offset = packet.GetHexMaxU32(false, UINT32_MAX);
617
if (packet.GetChar() == ',') {
618
std::string buffer;
619
if (packet.GetEscapedBinaryData(buffer)) {
620
NativeFile file(fd, File::eOpenOptionWriteOnly, false);
621
size_t count = buffer.size();
622
Status error =
623
file.Write(static_cast<const void *>(&buffer[0]), count, offset);
624
const int save_errno = error.GetError();
625
if (error.Success())
626
response.Printf("%zx", count);
627
else {
628
response.PutCString("-1");
629
if (save_errno)
630
response.Printf(",%x", system_errno_to_gdb(save_errno));
631
}
632
} else {
633
response.Printf("-1,%x", EINVAL);
634
}
635
return SendPacketNoLock(response.GetString());
636
}
637
}
638
return SendErrorResponse(27);
639
}
640
641
GDBRemoteCommunication::PacketResult
642
GDBRemoteCommunicationServerCommon::Handle_vFile_Size(
643
StringExtractorGDBRemote &packet) {
644
packet.SetFilePos(::strlen("vFile:size:"));
645
std::string path;
646
packet.GetHexByteString(path);
647
if (!path.empty()) {
648
uint64_t Size;
649
if (llvm::sys::fs::file_size(path, Size))
650
return SendErrorResponse(5);
651
StreamString response;
652
response.PutChar('F');
653
response.PutHex64(Size);
654
if (Size == UINT64_MAX) {
655
response.PutChar(',');
656
response.PutHex64(Size); // TODO: replace with Host::GetSyswideErrorCode()
657
}
658
return SendPacketNoLock(response.GetString());
659
}
660
return SendErrorResponse(22);
661
}
662
663
GDBRemoteCommunication::PacketResult
664
GDBRemoteCommunicationServerCommon::Handle_vFile_Mode(
665
StringExtractorGDBRemote &packet) {
666
packet.SetFilePos(::strlen("vFile:mode:"));
667
std::string path;
668
packet.GetHexByteString(path);
669
if (!path.empty()) {
670
FileSpec file_spec(path);
671
FileSystem::Instance().Resolve(file_spec);
672
std::error_code ec;
673
const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec);
674
StreamString response;
675
if (mode != llvm::sys::fs::perms_not_known)
676
response.Printf("F%x", mode);
677
else
678
response.Printf("F-1,%x", (int)Status(ec).GetError());
679
return SendPacketNoLock(response.GetString());
680
}
681
return SendErrorResponse(23);
682
}
683
684
GDBRemoteCommunication::PacketResult
685
GDBRemoteCommunicationServerCommon::Handle_vFile_Exists(
686
StringExtractorGDBRemote &packet) {
687
packet.SetFilePos(::strlen("vFile:exists:"));
688
std::string path;
689
packet.GetHexByteString(path);
690
if (!path.empty()) {
691
bool retcode = llvm::sys::fs::exists(path);
692
StreamString response;
693
response.PutChar('F');
694
response.PutChar(',');
695
if (retcode)
696
response.PutChar('1');
697
else
698
response.PutChar('0');
699
return SendPacketNoLock(response.GetString());
700
}
701
return SendErrorResponse(24);
702
}
703
704
GDBRemoteCommunication::PacketResult
705
GDBRemoteCommunicationServerCommon::Handle_vFile_symlink(
706
StringExtractorGDBRemote &packet) {
707
packet.SetFilePos(::strlen("vFile:symlink:"));
708
std::string dst, src;
709
packet.GetHexByteStringTerminatedBy(dst, ',');
710
packet.GetChar(); // Skip ',' char
711
packet.GetHexByteString(src);
712
713
FileSpec src_spec(src);
714
FileSystem::Instance().Resolve(src_spec);
715
Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst));
716
717
StreamString response;
718
response.Printf("F%x,%x", error.GetError(), error.GetError());
719
return SendPacketNoLock(response.GetString());
720
}
721
722
GDBRemoteCommunication::PacketResult
723
GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(
724
StringExtractorGDBRemote &packet) {
725
packet.SetFilePos(::strlen("vFile:unlink:"));
726
std::string path;
727
packet.GetHexByteString(path);
728
Status error(llvm::sys::fs::remove(path));
729
StreamString response;
730
response.Printf("F%x,%x", error.GetError(), error.GetError());
731
return SendPacketNoLock(response.GetString());
732
}
733
734
GDBRemoteCommunication::PacketResult
735
GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
736
StringExtractorGDBRemote &packet) {
737
packet.SetFilePos(::strlen("qPlatform_shell:"));
738
std::string path;
739
std::string working_dir;
740
packet.GetHexByteStringTerminatedBy(path, ',');
741
if (!path.empty()) {
742
if (packet.GetChar() == ',') {
743
// FIXME: add timeout to qPlatform_shell packet
744
// uint32_t timeout = packet.GetHexMaxU32(false, 32);
745
if (packet.GetChar() == ',')
746
packet.GetHexByteString(working_dir);
747
int status, signo;
748
std::string output;
749
FileSpec working_spec(working_dir);
750
FileSystem::Instance().Resolve(working_spec);
751
Status err =
752
Host::RunShellCommand(path.c_str(), working_spec, &status, &signo,
753
&output, std::chrono::seconds(10));
754
StreamGDBRemote response;
755
if (err.Fail()) {
756
response.PutCString("F,");
757
response.PutHex32(UINT32_MAX);
758
} else {
759
response.PutCString("F,");
760
response.PutHex32(status);
761
response.PutChar(',');
762
response.PutHex32(signo);
763
response.PutChar(',');
764
response.PutEscapedBytes(output.c_str(), output.size());
765
}
766
return SendPacketNoLock(response.GetString());
767
}
768
}
769
return SendErrorResponse(24);
770
}
771
772
template <typename T, typename U>
773
static void fill_clamp(T &dest, U src, typename T::value_type fallback) {
774
static_assert(std::is_unsigned<typename T::value_type>::value,
775
"Destination type must be unsigned.");
776
using UU = std::make_unsigned_t<U>;
777
constexpr auto T_max = std::numeric_limits<typename T::value_type>::max();
778
dest = src >= 0 && static_cast<UU>(src) <= T_max ? src : fallback;
779
}
780
781
GDBRemoteCommunication::PacketResult
782
GDBRemoteCommunicationServerCommon::Handle_vFile_FStat(
783
StringExtractorGDBRemote &packet) {
784
StreamGDBRemote response;
785
packet.SetFilePos(::strlen("vFile:fstat:"));
786
int fd = packet.GetS32(-1, 16);
787
788
struct stat file_stats;
789
if (::fstat(fd, &file_stats) == -1) {
790
const int save_errno = errno;
791
response.Printf("F-1,%x", system_errno_to_gdb(save_errno));
792
return SendPacketNoLock(response.GetString());
793
}
794
795
GDBRemoteFStatData data;
796
fill_clamp(data.gdb_st_dev, file_stats.st_dev, 0);
797
fill_clamp(data.gdb_st_ino, file_stats.st_ino, 0);
798
data.gdb_st_mode = file_stats.st_mode;
799
fill_clamp(data.gdb_st_nlink, file_stats.st_nlink, UINT32_MAX);
800
fill_clamp(data.gdb_st_uid, file_stats.st_uid, 0);
801
fill_clamp(data.gdb_st_gid, file_stats.st_gid, 0);
802
fill_clamp(data.gdb_st_rdev, file_stats.st_rdev, 0);
803
data.gdb_st_size = file_stats.st_size;
804
#if !defined(_WIN32)
805
data.gdb_st_blksize = file_stats.st_blksize;
806
data.gdb_st_blocks = file_stats.st_blocks;
807
#else
808
data.gdb_st_blksize = 0;
809
data.gdb_st_blocks = 0;
810
#endif
811
fill_clamp(data.gdb_st_atime, file_stats.st_atime, 0);
812
fill_clamp(data.gdb_st_mtime, file_stats.st_mtime, 0);
813
fill_clamp(data.gdb_st_ctime, file_stats.st_ctime, 0);
814
815
response.Printf("F%zx;", sizeof(data));
816
response.PutEscapedBytes(&data, sizeof(data));
817
return SendPacketNoLock(response.GetString());
818
}
819
820
GDBRemoteCommunication::PacketResult
821
GDBRemoteCommunicationServerCommon::Handle_vFile_Stat(
822
StringExtractorGDBRemote &packet) {
823
return SendUnimplementedResponse(
824
"GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
825
}
826
827
GDBRemoteCommunication::PacketResult
828
GDBRemoteCommunicationServerCommon::Handle_vFile_MD5(
829
StringExtractorGDBRemote &packet) {
830
packet.SetFilePos(::strlen("vFile:MD5:"));
831
std::string path;
832
packet.GetHexByteString(path);
833
if (!path.empty()) {
834
StreamGDBRemote response;
835
auto Result = llvm::sys::fs::md5_contents(path);
836
if (!Result) {
837
response.PutCString("F,");
838
response.PutCString("x");
839
} else {
840
response.PutCString("F,");
841
response.PutHex64(Result->low());
842
response.PutHex64(Result->high());
843
}
844
return SendPacketNoLock(response.GetString());
845
}
846
return SendErrorResponse(25);
847
}
848
849
GDBRemoteCommunication::PacketResult
850
GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir(
851
StringExtractorGDBRemote &packet) {
852
packet.SetFilePos(::strlen("qPlatform_mkdir:"));
853
mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
854
if (packet.GetChar() == ',') {
855
std::string path;
856
packet.GetHexByteString(path);
857
Status error(llvm::sys::fs::create_directory(path, mode));
858
859
StreamGDBRemote response;
860
response.Printf("F%x", error.GetError());
861
862
return SendPacketNoLock(response.GetString());
863
}
864
return SendErrorResponse(20);
865
}
866
867
GDBRemoteCommunication::PacketResult
868
GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod(
869
StringExtractorGDBRemote &packet) {
870
packet.SetFilePos(::strlen("qPlatform_chmod:"));
871
872
auto perms =
873
static_cast<llvm::sys::fs::perms>(packet.GetHexMaxU32(false, UINT32_MAX));
874
if (packet.GetChar() == ',') {
875
std::string path;
876
packet.GetHexByteString(path);
877
Status error(llvm::sys::fs::setPermissions(path, perms));
878
879
StreamGDBRemote response;
880
response.Printf("F%x", error.GetError());
881
882
return SendPacketNoLock(response.GetString());
883
}
884
return SendErrorResponse(19);
885
}
886
887
GDBRemoteCommunication::PacketResult
888
GDBRemoteCommunicationServerCommon::Handle_qSupported(
889
StringExtractorGDBRemote &packet) {
890
// Parse client-indicated features.
891
llvm::SmallVector<llvm::StringRef, 4> client_features;
892
packet.GetStringRef().split(client_features, ';');
893
return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";"));
894
}
895
896
GDBRemoteCommunication::PacketResult
897
GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError(
898
StringExtractorGDBRemote &packet) {
899
packet.SetFilePos(::strlen("QSetDetachOnError:"));
900
if (packet.GetU32(0))
901
m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
902
else
903
m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);
904
return SendOKResponse();
905
}
906
907
GDBRemoteCommunication::PacketResult
908
GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode(
909
StringExtractorGDBRemote &packet) {
910
// Send response first before changing m_send_acks to we ack this packet
911
PacketResult packet_result = SendOKResponse();
912
m_send_acks = false;
913
return packet_result;
914
}
915
916
GDBRemoteCommunication::PacketResult
917
GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN(
918
StringExtractorGDBRemote &packet) {
919
packet.SetFilePos(::strlen("QSetSTDIN:"));
920
FileAction file_action;
921
std::string path;
922
packet.GetHexByteString(path);
923
const bool read = true;
924
const bool write = false;
925
if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) {
926
m_process_launch_info.AppendFileAction(file_action);
927
return SendOKResponse();
928
}
929
return SendErrorResponse(15);
930
}
931
932
GDBRemoteCommunication::PacketResult
933
GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT(
934
StringExtractorGDBRemote &packet) {
935
packet.SetFilePos(::strlen("QSetSTDOUT:"));
936
FileAction file_action;
937
std::string path;
938
packet.GetHexByteString(path);
939
const bool read = false;
940
const bool write = true;
941
if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) {
942
m_process_launch_info.AppendFileAction(file_action);
943
return SendOKResponse();
944
}
945
return SendErrorResponse(16);
946
}
947
948
GDBRemoteCommunication::PacketResult
949
GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR(
950
StringExtractorGDBRemote &packet) {
951
packet.SetFilePos(::strlen("QSetSTDERR:"));
952
FileAction file_action;
953
std::string path;
954
packet.GetHexByteString(path);
955
const bool read = false;
956
const bool write = true;
957
if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) {
958
m_process_launch_info.AppendFileAction(file_action);
959
return SendOKResponse();
960
}
961
return SendErrorResponse(17);
962
}
963
964
GDBRemoteCommunication::PacketResult
965
GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess(
966
StringExtractorGDBRemote &packet) {
967
if (m_process_launch_error.Success())
968
return SendOKResponse();
969
StreamString response;
970
response.PutChar('E');
971
response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
972
return SendPacketNoLock(response.GetString());
973
}
974
975
GDBRemoteCommunication::PacketResult
976
GDBRemoteCommunicationServerCommon::Handle_QEnvironment(
977
StringExtractorGDBRemote &packet) {
978
packet.SetFilePos(::strlen("QEnvironment:"));
979
const uint32_t bytes_left = packet.GetBytesLeft();
980
if (bytes_left > 0) {
981
m_process_launch_info.GetEnvironment().insert(packet.Peek());
982
return SendOKResponse();
983
}
984
return SendErrorResponse(12);
985
}
986
987
GDBRemoteCommunication::PacketResult
988
GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded(
989
StringExtractorGDBRemote &packet) {
990
packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
991
const uint32_t bytes_left = packet.GetBytesLeft();
992
if (bytes_left > 0) {
993
std::string str;
994
packet.GetHexByteString(str);
995
m_process_launch_info.GetEnvironment().insert(str);
996
return SendOKResponse();
997
}
998
return SendErrorResponse(12);
999
}
1000
1001
GDBRemoteCommunication::PacketResult
1002
GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
1003
StringExtractorGDBRemote &packet) {
1004
packet.SetFilePos(::strlen("QLaunchArch:"));
1005
const uint32_t bytes_left = packet.GetBytesLeft();
1006
if (bytes_left > 0) {
1007
const char *arch_triple = packet.Peek();
1008
m_process_launch_info.SetArchitecture(
1009
HostInfo::GetAugmentedArchSpec(arch_triple));
1010
return SendOKResponse();
1011
}
1012
return SendErrorResponse(13);
1013
}
1014
1015
GDBRemoteCommunication::PacketResult
1016
GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
1017
// The 'A' packet is the most over designed packet ever here with redundant
1018
// argument indexes, redundant argument lengths and needed hex encoded
1019
// argument string values. Really all that is needed is a comma separated hex
1020
// encoded argument value list, but we will stay true to the documented
1021
// version of the 'A' packet here...
1022
1023
Log *log = GetLog(LLDBLog::Process);
1024
int actual_arg_index = 0;
1025
1026
packet.SetFilePos(1); // Skip the 'A'
1027
bool success = true;
1028
while (success && packet.GetBytesLeft() > 0) {
1029
// Decode the decimal argument string length. This length is the number of
1030
// hex nibbles in the argument string value.
1031
const uint32_t arg_len = packet.GetU32(UINT32_MAX);
1032
if (arg_len == UINT32_MAX)
1033
success = false;
1034
else {
1035
// Make sure the argument hex string length is followed by a comma
1036
if (packet.GetChar() != ',')
1037
success = false;
1038
else {
1039
// Decode the argument index. We ignore this really because who would
1040
// really send down the arguments in a random order???
1041
const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
1042
if (arg_idx == UINT32_MAX)
1043
success = false;
1044
else {
1045
// Make sure the argument index is followed by a comma
1046
if (packet.GetChar() != ',')
1047
success = false;
1048
else {
1049
// Decode the argument string value from hex bytes back into a UTF8
1050
// string and make sure the length matches the one supplied in the
1051
// packet
1052
std::string arg;
1053
if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
1054
(arg_len / 2))
1055
success = false;
1056
else {
1057
// If there are any bytes left
1058
if (packet.GetBytesLeft()) {
1059
if (packet.GetChar() != ',')
1060
success = false;
1061
}
1062
1063
if (success) {
1064
if (arg_idx == 0)
1065
m_process_launch_info.GetExecutableFile().SetFile(
1066
arg, FileSpec::Style::native);
1067
m_process_launch_info.GetArguments().AppendArgument(arg);
1068
LLDB_LOGF(log, "LLGSPacketHandler::%s added arg %d: \"%s\"",
1069
__FUNCTION__, actual_arg_index, arg.c_str());
1070
++actual_arg_index;
1071
}
1072
}
1073
}
1074
}
1075
}
1076
}
1077
}
1078
1079
if (success) {
1080
m_process_launch_error = LaunchProcess();
1081
if (m_process_launch_error.Success())
1082
return SendOKResponse();
1083
LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error);
1084
}
1085
return SendErrorResponse(8);
1086
}
1087
1088
GDBRemoteCommunication::PacketResult
1089
GDBRemoteCommunicationServerCommon::Handle_qEcho(
1090
StringExtractorGDBRemote &packet) {
1091
// Just echo back the exact same packet for qEcho...
1092
return SendPacketNoLock(packet.GetStringRef());
1093
}
1094
1095
GDBRemoteCommunication::PacketResult
1096
GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(
1097
StringExtractorGDBRemote &packet) {
1098
packet.SetFilePos(::strlen("qModuleInfo:"));
1099
1100
std::string module_path;
1101
packet.GetHexByteStringTerminatedBy(module_path, ';');
1102
if (module_path.empty())
1103
return SendErrorResponse(1);
1104
1105
if (packet.GetChar() != ';')
1106
return SendErrorResponse(2);
1107
1108
std::string triple;
1109
packet.GetHexByteString(triple);
1110
1111
ModuleSpec matched_module_spec = GetModuleInfo(module_path, triple);
1112
if (!matched_module_spec.GetFileSpec())
1113
return SendErrorResponse(3);
1114
1115
const auto file_offset = matched_module_spec.GetObjectOffset();
1116
const auto file_size = matched_module_spec.GetObjectSize();
1117
const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
1118
1119
StreamGDBRemote response;
1120
1121
if (uuid_str.empty()) {
1122
auto Result = llvm::sys::fs::md5_contents(
1123
matched_module_spec.GetFileSpec().GetPath());
1124
if (!Result)
1125
return SendErrorResponse(5);
1126
response.PutCString("md5:");
1127
response.PutStringAsRawHex8(Result->digest());
1128
} else {
1129
response.PutCString("uuid:");
1130
response.PutStringAsRawHex8(uuid_str);
1131
}
1132
response.PutChar(';');
1133
1134
const auto &module_arch = matched_module_spec.GetArchitecture();
1135
response.PutCString("triple:");
1136
response.PutStringAsRawHex8(module_arch.GetTriple().getTriple());
1137
response.PutChar(';');
1138
1139
response.PutCString("file_path:");
1140
response.PutStringAsRawHex8(
1141
matched_module_spec.GetFileSpec().GetPath().c_str());
1142
response.PutChar(';');
1143
response.PutCString("file_offset:");
1144
response.PutHex64(file_offset);
1145
response.PutChar(';');
1146
response.PutCString("file_size:");
1147
response.PutHex64(file_size);
1148
response.PutChar(';');
1149
1150
return SendPacketNoLock(response.GetString());
1151
}
1152
1153
GDBRemoteCommunication::PacketResult
1154
GDBRemoteCommunicationServerCommon::Handle_jModulesInfo(
1155
StringExtractorGDBRemote &packet) {
1156
namespace json = llvm::json;
1157
1158
packet.SetFilePos(::strlen("jModulesInfo:"));
1159
1160
StructuredData::ObjectSP object_sp = StructuredData::ParseJSON(packet.Peek());
1161
if (!object_sp)
1162
return SendErrorResponse(1);
1163
1164
StructuredData::Array *packet_array = object_sp->GetAsArray();
1165
if (!packet_array)
1166
return SendErrorResponse(2);
1167
1168
json::Array response_array;
1169
for (size_t i = 0; i < packet_array->GetSize(); ++i) {
1170
StructuredData::Dictionary *query =
1171
packet_array->GetItemAtIndex(i)->GetAsDictionary();
1172
if (!query)
1173
continue;
1174
llvm::StringRef file, triple;
1175
if (!query->GetValueForKeyAsString("file", file) ||
1176
!query->GetValueForKeyAsString("triple", triple))
1177
continue;
1178
1179
ModuleSpec matched_module_spec = GetModuleInfo(file, triple);
1180
if (!matched_module_spec.GetFileSpec())
1181
continue;
1182
1183
const auto file_offset = matched_module_spec.GetObjectOffset();
1184
const auto file_size = matched_module_spec.GetObjectSize();
1185
const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
1186
if (uuid_str.empty())
1187
continue;
1188
const auto triple_str =
1189
matched_module_spec.GetArchitecture().GetTriple().getTriple();
1190
const auto file_path = matched_module_spec.GetFileSpec().GetPath();
1191
1192
json::Object response{{"uuid", uuid_str},
1193
{"triple", triple_str},
1194
{"file_path", file_path},
1195
{"file_offset", static_cast<int64_t>(file_offset)},
1196
{"file_size", static_cast<int64_t>(file_size)}};
1197
response_array.push_back(std::move(response));
1198
}
1199
1200
StreamString response;
1201
response.AsRawOstream() << std::move(response_array);
1202
StreamGDBRemote escaped_response;
1203
escaped_response.PutEscapedBytes(response.GetString().data(),
1204
response.GetSize());
1205
return SendPacketNoLock(escaped_response.GetString());
1206
}
1207
1208
void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
1209
const ProcessInstanceInfo &proc_info, StreamString &response) {
1210
response.Printf(
1211
"pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
1212
proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1213
proc_info.GetUserID(), proc_info.GetGroupID(),
1214
proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
1215
response.PutCString("name:");
1216
response.PutStringAsRawHex8(proc_info.GetExecutableFile().GetPath().c_str());
1217
1218
response.PutChar(';');
1219
response.PutCString("args:");
1220
response.PutStringAsRawHex8(proc_info.GetArg0());
1221
for (auto &arg : proc_info.GetArguments()) {
1222
response.PutChar('-');
1223
response.PutStringAsRawHex8(arg.ref());
1224
}
1225
1226
response.PutChar(';');
1227
const ArchSpec &proc_arch = proc_info.GetArchitecture();
1228
if (proc_arch.IsValid()) {
1229
const llvm::Triple &proc_triple = proc_arch.GetTriple();
1230
response.PutCString("triple:");
1231
response.PutStringAsRawHex8(proc_triple.getTriple());
1232
response.PutChar(';');
1233
}
1234
}
1235
1236
void GDBRemoteCommunicationServerCommon::
1237
CreateProcessInfoResponse_DebugServerStyle(
1238
const ProcessInstanceInfo &proc_info, StreamString &response) {
1239
response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64
1240
";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
1241
proc_info.GetProcessID(), proc_info.GetParentProcessID(),
1242
proc_info.GetUserID(), proc_info.GetGroupID(),
1243
proc_info.GetEffectiveUserID(),
1244
proc_info.GetEffectiveGroupID());
1245
1246
const ArchSpec &proc_arch = proc_info.GetArchitecture();
1247
if (proc_arch.IsValid()) {
1248
const llvm::Triple &proc_triple = proc_arch.GetTriple();
1249
#if defined(__APPLE__)
1250
// We'll send cputype/cpusubtype.
1251
const uint32_t cpu_type = proc_arch.GetMachOCPUType();
1252
if (cpu_type != 0)
1253
response.Printf("cputype:%" PRIx32 ";", cpu_type);
1254
1255
const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
1256
if (cpu_subtype != 0)
1257
response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);
1258
1259
const std::string vendor = proc_triple.getVendorName().str();
1260
if (!vendor.empty())
1261
response.Printf("vendor:%s;", vendor.c_str());
1262
#else
1263
// We'll send the triple.
1264
response.PutCString("triple:");
1265
response.PutStringAsRawHex8(proc_triple.getTriple());
1266
response.PutChar(';');
1267
#endif
1268
std::string ostype = std::string(proc_triple.getOSName());
1269
// Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
1270
if (proc_triple.getVendor() == llvm::Triple::Apple) {
1271
switch (proc_triple.getArch()) {
1272
case llvm::Triple::arm:
1273
case llvm::Triple::thumb:
1274
case llvm::Triple::aarch64:
1275
case llvm::Triple::aarch64_32:
1276
ostype = "ios";
1277
break;
1278
default:
1279
// No change.
1280
break;
1281
}
1282
}
1283
response.Printf("ostype:%s;", ostype.c_str());
1284
1285
switch (proc_arch.GetByteOrder()) {
1286
case lldb::eByteOrderLittle:
1287
response.PutCString("endian:little;");
1288
break;
1289
case lldb::eByteOrderBig:
1290
response.PutCString("endian:big;");
1291
break;
1292
case lldb::eByteOrderPDP:
1293
response.PutCString("endian:pdp;");
1294
break;
1295
default:
1296
// Nothing.
1297
break;
1298
}
1299
// In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer
1300
// size is 4 and for N64 it is 8
1301
std::string abi = proc_arch.GetTargetABI();
1302
if (!abi.empty())
1303
response.Printf("elf_abi:%s;", abi.c_str());
1304
response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
1305
}
1306
}
1307
1308
FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(
1309
const std::string &module_path, const ArchSpec &arch) {
1310
#ifdef __ANDROID__
1311
return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
1312
#else
1313
FileSpec file_spec(module_path);
1314
FileSystem::Instance().Resolve(file_spec);
1315
return file_spec;
1316
#endif
1317
}
1318
1319
ModuleSpec
1320
GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path,
1321
llvm::StringRef triple) {
1322
ArchSpec arch(triple);
1323
1324
FileSpec req_module_path_spec(module_path);
1325
FileSystem::Instance().Resolve(req_module_path_spec);
1326
1327
const FileSpec module_path_spec =
1328
FindModuleFile(req_module_path_spec.GetPath(), arch);
1329
1330
lldb::offset_t file_offset = 0;
1331
lldb::offset_t file_size = 0;
1332
#ifdef __ANDROID__
1333
// In Android API level 23 and above, dynamic loader is able to load .so file
1334
// directly from zip file. In that case, module_path will be
1335
// "zip_path!/so_path". Resolve the zip file path, .so file offset and size.
1336
ZipFileResolver::FileKind file_kind = ZipFileResolver::eFileKindInvalid;
1337
std::string file_path;
1338
if (!ZipFileResolver::ResolveSharedLibraryPath(
1339
module_path_spec, file_kind, file_path, file_offset, file_size)) {
1340
return ModuleSpec();
1341
}
1342
lldbassert(file_kind != ZipFileResolver::eFileKindInvalid);
1343
// For zip .so file, this file_path will contain only the actual zip file
1344
// path for the object file processing. Otherwise it is the same as
1345
// module_path.
1346
const FileSpec actual_module_path_spec(file_path);
1347
#else
1348
// It is just module_path_spec reference for other platforms.
1349
const FileSpec &actual_module_path_spec = module_path_spec;
1350
#endif
1351
1352
const ModuleSpec module_spec(actual_module_path_spec, arch);
1353
1354
ModuleSpecList module_specs;
1355
if (!ObjectFile::GetModuleSpecifications(actual_module_path_spec, file_offset,
1356
file_size, module_specs))
1357
return ModuleSpec();
1358
1359
ModuleSpec matched_module_spec;
1360
if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
1361
return ModuleSpec();
1362
1363
#ifdef __ANDROID__
1364
if (file_kind == ZipFileResolver::eFileKindZip) {
1365
// For zip .so file, matched_module_spec contains only the actual zip file
1366
// path for the object file processing. Overwrite the matched_module_spec
1367
// file spec with the original module_path_spec to pass "zip_path!/so_path"
1368
// through to PlatformAndroid::DownloadModuleSlice.
1369
*matched_module_spec.GetFileSpecPtr() = module_path_spec;
1370
}
1371
#endif
1372
1373
return matched_module_spec;
1374
}
1375
1376
std::vector<std::string> GDBRemoteCommunicationServerCommon::HandleFeatures(
1377
const llvm::ArrayRef<llvm::StringRef> client_features) {
1378
// 128KBytes is a reasonable max packet size--debugger can always use less.
1379
constexpr uint32_t max_packet_size = 128 * 1024;
1380
1381
// Features common to platform server and llgs.
1382
return {
1383
llvm::formatv("PacketSize={0}", max_packet_size),
1384
"QStartNoAckMode+",
1385
"qEcho+",
1386
"native-signals+",
1387
};
1388
}
1389
1390