1 | //===-- SBPlatform.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 "lldb/API/SBPlatform.h" |
10 | #include "lldb/API/SBDebugger.h" |
11 | #include "lldb/API/SBEnvironment.h" |
12 | #include "lldb/API/SBError.h" |
13 | #include "lldb/API/SBFileSpec.h" |
14 | #include "lldb/API/SBLaunchInfo.h" |
15 | #include "lldb/API/SBModuleSpec.h" |
16 | #include "lldb/API/SBPlatform.h" |
17 | #include "lldb/API/SBProcessInfoList.h" |
18 | #include "lldb/API/SBTarget.h" |
19 | #include "lldb/API/SBUnixSignals.h" |
20 | #include "lldb/Host/File.h" |
21 | #include "lldb/Target/Platform.h" |
22 | #include "lldb/Target/Target.h" |
23 | #include "lldb/Utility/ArchSpec.h" |
24 | #include "lldb/Utility/Args.h" |
25 | #include "lldb/Utility/Instrumentation.h" |
26 | #include "lldb/Utility/Status.h" |
27 | |
28 | #include "llvm/Support/FileSystem.h" |
29 | |
30 | #include <functional> |
31 | |
32 | using namespace lldb; |
33 | using namespace lldb_private; |
34 | |
35 | // PlatformConnectOptions |
36 | struct PlatformConnectOptions { |
37 | PlatformConnectOptions(const char *url = nullptr) { |
38 | if (url && url[0]) |
39 | m_url = url; |
40 | } |
41 | |
42 | ~PlatformConnectOptions() = default; |
43 | |
44 | std::string m_url; |
45 | std::string m_rsync_options; |
46 | std::string m_rsync_remote_path_prefix; |
47 | bool m_rsync_enabled = false; |
48 | bool m_rsync_omit_hostname_from_remote_path = false; |
49 | ConstString m_local_cache_directory; |
50 | }; |
51 | |
52 | // PlatformShellCommand |
53 | struct PlatformShellCommand { |
54 | PlatformShellCommand(llvm::StringRef shell_interpreter, |
55 | llvm::StringRef shell_command) { |
56 | if (!shell_interpreter.empty()) |
57 | m_shell = shell_interpreter.str(); |
58 | |
59 | if (!m_shell.empty() && !shell_command.empty()) |
60 | m_command = shell_command.str(); |
61 | } |
62 | |
63 | PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef()) { |
64 | if (!shell_command.empty()) |
65 | m_command = shell_command.str(); |
66 | } |
67 | |
68 | ~PlatformShellCommand() = default; |
69 | |
70 | std::string m_shell; |
71 | std::string m_command; |
72 | std::string m_working_dir; |
73 | std::string m_output; |
74 | int m_status = 0; |
75 | int m_signo = 0; |
76 | Timeout<std::ratio<1>> m_timeout = std::nullopt; |
77 | }; |
78 | // SBPlatformConnectOptions |
79 | SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url) |
80 | : m_opaque_ptr(new PlatformConnectOptions(url)) { |
81 | LLDB_INSTRUMENT_VA(this, url); |
82 | } |
83 | |
84 | SBPlatformConnectOptions::SBPlatformConnectOptions( |
85 | const SBPlatformConnectOptions &rhs) |
86 | : m_opaque_ptr(new PlatformConnectOptions()) { |
87 | LLDB_INSTRUMENT_VA(this, rhs); |
88 | |
89 | *m_opaque_ptr = *rhs.m_opaque_ptr; |
90 | } |
91 | |
92 | SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; } |
93 | |
94 | SBPlatformConnectOptions & |
95 | SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) { |
96 | LLDB_INSTRUMENT_VA(this, rhs); |
97 | |
98 | *m_opaque_ptr = *rhs.m_opaque_ptr; |
99 | return *this; |
100 | } |
101 | |
102 | const char *SBPlatformConnectOptions::GetURL() { |
103 | LLDB_INSTRUMENT_VA(this); |
104 | |
105 | if (m_opaque_ptr->m_url.empty()) |
106 | return nullptr; |
107 | return ConstString(m_opaque_ptr->m_url.c_str()).GetCString(); |
108 | } |
109 | |
110 | void SBPlatformConnectOptions::SetURL(const char *url) { |
111 | LLDB_INSTRUMENT_VA(this, url); |
112 | |
113 | if (url && url[0]) |
114 | m_opaque_ptr->m_url = url; |
115 | else |
116 | m_opaque_ptr->m_url.clear(); |
117 | } |
118 | |
119 | bool SBPlatformConnectOptions::GetRsyncEnabled() { |
120 | LLDB_INSTRUMENT_VA(this); |
121 | |
122 | return m_opaque_ptr->m_rsync_enabled; |
123 | } |
124 | |
125 | void SBPlatformConnectOptions::EnableRsync( |
126 | const char *options, const char *remote_path_prefix, |
127 | bool omit_hostname_from_remote_path) { |
128 | LLDB_INSTRUMENT_VA(this, options, remote_path_prefix, |
129 | omit_hostname_from_remote_path); |
130 | |
131 | m_opaque_ptr->m_rsync_enabled = true; |
132 | m_opaque_ptr->m_rsync_omit_hostname_from_remote_path = |
133 | omit_hostname_from_remote_path; |
134 | if (remote_path_prefix && remote_path_prefix[0]) |
135 | m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix; |
136 | else |
137 | m_opaque_ptr->m_rsync_remote_path_prefix.clear(); |
138 | |
139 | if (options && options[0]) |
140 | m_opaque_ptr->m_rsync_options = options; |
141 | else |
142 | m_opaque_ptr->m_rsync_options.clear(); |
143 | } |
144 | |
145 | void SBPlatformConnectOptions::DisableRsync() { |
146 | LLDB_INSTRUMENT_VA(this); |
147 | |
148 | m_opaque_ptr->m_rsync_enabled = false; |
149 | } |
150 | |
151 | const char *SBPlatformConnectOptions::GetLocalCacheDirectory() { |
152 | LLDB_INSTRUMENT_VA(this); |
153 | |
154 | return m_opaque_ptr->m_local_cache_directory.GetCString(); |
155 | } |
156 | |
157 | void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) { |
158 | LLDB_INSTRUMENT_VA(this, path); |
159 | |
160 | if (path && path[0]) |
161 | m_opaque_ptr->m_local_cache_directory.SetCString(path); |
162 | else |
163 | m_opaque_ptr->m_local_cache_directory = ConstString(); |
164 | } |
165 | |
166 | // SBPlatformShellCommand |
167 | SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_interpreter, |
168 | const char *shell_command) |
169 | : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) { |
170 | LLDB_INSTRUMENT_VA(this, shell_interpreter, shell_command); |
171 | } |
172 | |
173 | SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command) |
174 | : m_opaque_ptr(new PlatformShellCommand(shell_command)) { |
175 | LLDB_INSTRUMENT_VA(this, shell_command); |
176 | } |
177 | |
178 | SBPlatformShellCommand::SBPlatformShellCommand( |
179 | const SBPlatformShellCommand &rhs) |
180 | : m_opaque_ptr(new PlatformShellCommand()) { |
181 | LLDB_INSTRUMENT_VA(this, rhs); |
182 | |
183 | *m_opaque_ptr = *rhs.m_opaque_ptr; |
184 | } |
185 | |
186 | SBPlatformShellCommand & |
187 | SBPlatformShellCommand::operator=(const SBPlatformShellCommand &rhs) { |
188 | |
189 | LLDB_INSTRUMENT_VA(this, rhs); |
190 | |
191 | *m_opaque_ptr = *rhs.m_opaque_ptr; |
192 | return *this; |
193 | } |
194 | |
195 | SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; } |
196 | |
197 | void SBPlatformShellCommand::Clear() { |
198 | LLDB_INSTRUMENT_VA(this); |
199 | |
200 | m_opaque_ptr->m_output = std::string(); |
201 | m_opaque_ptr->m_status = 0; |
202 | m_opaque_ptr->m_signo = 0; |
203 | } |
204 | |
205 | const char *SBPlatformShellCommand::GetShell() { |
206 | LLDB_INSTRUMENT_VA(this); |
207 | |
208 | if (m_opaque_ptr->m_shell.empty()) |
209 | return nullptr; |
210 | return ConstString(m_opaque_ptr->m_shell.c_str()).GetCString(); |
211 | } |
212 | |
213 | void SBPlatformShellCommand::SetShell(const char *shell_interpreter) { |
214 | LLDB_INSTRUMENT_VA(this, shell_interpreter); |
215 | |
216 | if (shell_interpreter && shell_interpreter[0]) |
217 | m_opaque_ptr->m_shell = shell_interpreter; |
218 | else |
219 | m_opaque_ptr->m_shell.clear(); |
220 | } |
221 | |
222 | const char *SBPlatformShellCommand::GetCommand() { |
223 | LLDB_INSTRUMENT_VA(this); |
224 | |
225 | if (m_opaque_ptr->m_command.empty()) |
226 | return nullptr; |
227 | return ConstString(m_opaque_ptr->m_command.c_str()).GetCString(); |
228 | } |
229 | |
230 | void SBPlatformShellCommand::SetCommand(const char *shell_command) { |
231 | LLDB_INSTRUMENT_VA(this, shell_command); |
232 | |
233 | if (shell_command && shell_command[0]) |
234 | m_opaque_ptr->m_command = shell_command; |
235 | else |
236 | m_opaque_ptr->m_command.clear(); |
237 | } |
238 | |
239 | const char *SBPlatformShellCommand::GetWorkingDirectory() { |
240 | LLDB_INSTRUMENT_VA(this); |
241 | |
242 | if (m_opaque_ptr->m_working_dir.empty()) |
243 | return nullptr; |
244 | return ConstString(m_opaque_ptr->m_working_dir.c_str()).GetCString(); |
245 | } |
246 | |
247 | void SBPlatformShellCommand::SetWorkingDirectory(const char *path) { |
248 | LLDB_INSTRUMENT_VA(this, path); |
249 | |
250 | if (path && path[0]) |
251 | m_opaque_ptr->m_working_dir = path; |
252 | else |
253 | m_opaque_ptr->m_working_dir.clear(); |
254 | } |
255 | |
256 | uint32_t SBPlatformShellCommand::GetTimeoutSeconds() { |
257 | LLDB_INSTRUMENT_VA(this); |
258 | |
259 | if (m_opaque_ptr->m_timeout) |
260 | return m_opaque_ptr->m_timeout->count(); |
261 | return UINT32_MAX; |
262 | } |
263 | |
264 | void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) { |
265 | LLDB_INSTRUMENT_VA(this, sec); |
266 | |
267 | if (sec == UINT32_MAX) |
268 | m_opaque_ptr->m_timeout = std::nullopt; |
269 | else |
270 | m_opaque_ptr->m_timeout = std::chrono::seconds(sec); |
271 | } |
272 | |
273 | int SBPlatformShellCommand::GetSignal() { |
274 | LLDB_INSTRUMENT_VA(this); |
275 | |
276 | return m_opaque_ptr->m_signo; |
277 | } |
278 | |
279 | int SBPlatformShellCommand::GetStatus() { |
280 | LLDB_INSTRUMENT_VA(this); |
281 | |
282 | return m_opaque_ptr->m_status; |
283 | } |
284 | |
285 | const char *SBPlatformShellCommand::GetOutput() { |
286 | LLDB_INSTRUMENT_VA(this); |
287 | |
288 | if (m_opaque_ptr->m_output.empty()) |
289 | return nullptr; |
290 | return ConstString(m_opaque_ptr->m_output.c_str()).GetCString(); |
291 | } |
292 | |
293 | // SBPlatform |
294 | SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); } |
295 | |
296 | SBPlatform::SBPlatform(const char *platform_name) { |
297 | LLDB_INSTRUMENT_VA(this, platform_name); |
298 | |
299 | m_opaque_sp = Platform::Create(name: platform_name); |
300 | } |
301 | |
302 | SBPlatform::SBPlatform(const SBPlatform &rhs) { |
303 | LLDB_INSTRUMENT_VA(this, rhs); |
304 | |
305 | m_opaque_sp = rhs.m_opaque_sp; |
306 | } |
307 | |
308 | SBPlatform &SBPlatform::operator=(const SBPlatform &rhs) { |
309 | LLDB_INSTRUMENT_VA(this, rhs); |
310 | |
311 | m_opaque_sp = rhs.m_opaque_sp; |
312 | return *this; |
313 | } |
314 | |
315 | SBPlatform::~SBPlatform() = default; |
316 | |
317 | SBPlatform SBPlatform::GetHostPlatform() { |
318 | LLDB_INSTRUMENT(); |
319 | |
320 | SBPlatform host_platform; |
321 | host_platform.m_opaque_sp = Platform::GetHostPlatform(); |
322 | return host_platform; |
323 | } |
324 | |
325 | bool SBPlatform::IsValid() const { |
326 | LLDB_INSTRUMENT_VA(this); |
327 | return this->operator bool(); |
328 | } |
329 | SBPlatform::operator bool() const { |
330 | LLDB_INSTRUMENT_VA(this); |
331 | |
332 | return m_opaque_sp.get() != nullptr; |
333 | } |
334 | |
335 | void SBPlatform::Clear() { |
336 | LLDB_INSTRUMENT_VA(this); |
337 | |
338 | m_opaque_sp.reset(); |
339 | } |
340 | |
341 | const char *SBPlatform::GetName() { |
342 | LLDB_INSTRUMENT_VA(this); |
343 | |
344 | PlatformSP platform_sp(GetSP()); |
345 | if (platform_sp) |
346 | return ConstString(platform_sp->GetName()).AsCString(); |
347 | return nullptr; |
348 | } |
349 | |
350 | lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; } |
351 | |
352 | void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) { |
353 | m_opaque_sp = platform_sp; |
354 | } |
355 | |
356 | const char *SBPlatform::GetWorkingDirectory() { |
357 | LLDB_INSTRUMENT_VA(this); |
358 | |
359 | PlatformSP platform_sp(GetSP()); |
360 | if (platform_sp) |
361 | return platform_sp->GetWorkingDirectory().GetPathAsConstString().AsCString(); |
362 | return nullptr; |
363 | } |
364 | |
365 | bool SBPlatform::SetWorkingDirectory(const char *path) { |
366 | LLDB_INSTRUMENT_VA(this, path); |
367 | |
368 | PlatformSP platform_sp(GetSP()); |
369 | if (platform_sp) { |
370 | if (path) |
371 | platform_sp->SetWorkingDirectory(FileSpec(path)); |
372 | else |
373 | platform_sp->SetWorkingDirectory(FileSpec()); |
374 | return true; |
375 | } |
376 | return false; |
377 | } |
378 | |
379 | SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) { |
380 | LLDB_INSTRUMENT_VA(this, connect_options); |
381 | |
382 | SBError sb_error; |
383 | PlatformSP platform_sp(GetSP()); |
384 | if (platform_sp && connect_options.GetURL()) { |
385 | Args args; |
386 | args.AppendArgument(arg_str: connect_options.GetURL()); |
387 | sb_error.ref() = platform_sp->ConnectRemote(args); |
388 | } else { |
389 | sb_error.SetErrorString("invalid platform" ); |
390 | } |
391 | return sb_error; |
392 | } |
393 | |
394 | void SBPlatform::DisconnectRemote() { |
395 | LLDB_INSTRUMENT_VA(this); |
396 | |
397 | PlatformSP platform_sp(GetSP()); |
398 | if (platform_sp) |
399 | platform_sp->DisconnectRemote(); |
400 | } |
401 | |
402 | bool SBPlatform::IsConnected() { |
403 | LLDB_INSTRUMENT_VA(this); |
404 | |
405 | PlatformSP platform_sp(GetSP()); |
406 | if (platform_sp) |
407 | return platform_sp->IsConnected(); |
408 | return false; |
409 | } |
410 | |
411 | const char *SBPlatform::GetTriple() { |
412 | LLDB_INSTRUMENT_VA(this); |
413 | |
414 | PlatformSP platform_sp(GetSP()); |
415 | if (platform_sp) { |
416 | ArchSpec arch(platform_sp->GetSystemArchitecture()); |
417 | if (arch.IsValid()) { |
418 | // Const-ify the string so we don't need to worry about the lifetime of |
419 | // the string |
420 | return ConstString(arch.GetTriple().getTriple().c_str()).GetCString(); |
421 | } |
422 | } |
423 | return nullptr; |
424 | } |
425 | |
426 | const char *SBPlatform::GetOSBuild() { |
427 | LLDB_INSTRUMENT_VA(this); |
428 | |
429 | PlatformSP platform_sp(GetSP()); |
430 | if (platform_sp) { |
431 | std::string s = platform_sp->GetOSBuildString().value_or(u: "" ); |
432 | if (!s.empty()) { |
433 | // Const-ify the string so we don't need to worry about the lifetime of |
434 | // the string |
435 | return ConstString(s).GetCString(); |
436 | } |
437 | } |
438 | return nullptr; |
439 | } |
440 | |
441 | const char *SBPlatform::GetOSDescription() { |
442 | LLDB_INSTRUMENT_VA(this); |
443 | |
444 | PlatformSP platform_sp(GetSP()); |
445 | if (platform_sp) { |
446 | std::string s = platform_sp->GetOSKernelDescription().value_or(u: "" ); |
447 | if (!s.empty()) { |
448 | // Const-ify the string so we don't need to worry about the lifetime of |
449 | // the string |
450 | return ConstString(s.c_str()).GetCString(); |
451 | } |
452 | } |
453 | return nullptr; |
454 | } |
455 | |
456 | const char *SBPlatform::GetHostname() { |
457 | LLDB_INSTRUMENT_VA(this); |
458 | |
459 | PlatformSP platform_sp(GetSP()); |
460 | if (platform_sp) |
461 | return ConstString(platform_sp->GetHostname()).GetCString(); |
462 | return nullptr; |
463 | } |
464 | |
465 | uint32_t SBPlatform::GetOSMajorVersion() { |
466 | LLDB_INSTRUMENT_VA(this); |
467 | |
468 | llvm::VersionTuple version; |
469 | if (PlatformSP platform_sp = GetSP()) |
470 | version = platform_sp->GetOSVersion(); |
471 | return version.empty() ? UINT32_MAX : version.getMajor(); |
472 | } |
473 | |
474 | uint32_t SBPlatform::GetOSMinorVersion() { |
475 | LLDB_INSTRUMENT_VA(this); |
476 | |
477 | llvm::VersionTuple version; |
478 | if (PlatformSP platform_sp = GetSP()) |
479 | version = platform_sp->GetOSVersion(); |
480 | return version.getMinor().value_or(UINT32_MAX); |
481 | } |
482 | |
483 | uint32_t SBPlatform::GetOSUpdateVersion() { |
484 | LLDB_INSTRUMENT_VA(this); |
485 | |
486 | llvm::VersionTuple version; |
487 | if (PlatformSP platform_sp = GetSP()) |
488 | version = platform_sp->GetOSVersion(); |
489 | return version.getSubminor().value_or(UINT32_MAX); |
490 | } |
491 | |
492 | void SBPlatform::SetSDKRoot(const char *sysroot) { |
493 | LLDB_INSTRUMENT_VA(this, sysroot); |
494 | if (PlatformSP platform_sp = GetSP()) |
495 | platform_sp->SetSDKRootDirectory(llvm::StringRef(sysroot).str()); |
496 | } |
497 | |
498 | SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) { |
499 | LLDB_INSTRUMENT_VA(this, src, dst); |
500 | |
501 | SBError sb_error; |
502 | PlatformSP platform_sp(GetSP()); |
503 | if (platform_sp) { |
504 | sb_error.ref() = platform_sp->GetFile(source: src.ref(), destination: dst.ref()); |
505 | } else { |
506 | sb_error.SetErrorString("invalid platform" ); |
507 | } |
508 | return sb_error; |
509 | } |
510 | |
511 | SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) { |
512 | LLDB_INSTRUMENT_VA(this, src, dst); |
513 | return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) { |
514 | if (src.Exists()) { |
515 | uint32_t permissions = FileSystem::Instance().GetPermissions(file_spec: src.ref()); |
516 | if (permissions == 0) { |
517 | if (FileSystem::Instance().IsDirectory(file_spec: src.ref())) |
518 | permissions = eFilePermissionsDirectoryDefault; |
519 | else |
520 | permissions = eFilePermissionsFileDefault; |
521 | } |
522 | |
523 | return platform_sp->PutFile(source: src.ref(), destination: dst.ref(), uid: permissions); |
524 | } |
525 | |
526 | Status error; |
527 | error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'" , |
528 | src.ref().GetPath().c_str()); |
529 | return error; |
530 | }); |
531 | } |
532 | |
533 | SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) { |
534 | LLDB_INSTRUMENT_VA(this, src, dst); |
535 | return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) { |
536 | if (src.Exists()) |
537 | return platform_sp->Install(src: src.ref(), dst: dst.ref()); |
538 | |
539 | Status error; |
540 | error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'" , |
541 | src.ref().GetPath().c_str()); |
542 | return error; |
543 | }); |
544 | } |
545 | |
546 | SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) { |
547 | LLDB_INSTRUMENT_VA(this, shell_command); |
548 | return ExecuteConnected( |
549 | func: [&](const lldb::PlatformSP &platform_sp) { |
550 | const char *command = shell_command.GetCommand(); |
551 | if (!command) |
552 | return Status("invalid shell command (empty)" ); |
553 | |
554 | if (shell_command.GetWorkingDirectory() == nullptr) { |
555 | std::string platform_working_dir = |
556 | platform_sp->GetWorkingDirectory().GetPath(); |
557 | if (!platform_working_dir.empty()) |
558 | shell_command.SetWorkingDirectory(platform_working_dir.c_str()); |
559 | } |
560 | return platform_sp->RunShellCommand( |
561 | shell: shell_command.m_opaque_ptr->m_shell, command, |
562 | working_dir: FileSpec(shell_command.GetWorkingDirectory()), |
563 | status_ptr: &shell_command.m_opaque_ptr->m_status, |
564 | signo_ptr: &shell_command.m_opaque_ptr->m_signo, |
565 | command_output: &shell_command.m_opaque_ptr->m_output, |
566 | timeout: shell_command.m_opaque_ptr->m_timeout); |
567 | }); |
568 | } |
569 | |
570 | SBError SBPlatform::Launch(SBLaunchInfo &launch_info) { |
571 | LLDB_INSTRUMENT_VA(this, launch_info); |
572 | return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) { |
573 | ProcessLaunchInfo info = launch_info.ref(); |
574 | Status error = platform_sp->LaunchProcess(launch_info&: info); |
575 | launch_info.set_ref(info); |
576 | return error; |
577 | }); |
578 | } |
579 | |
580 | SBProcess SBPlatform::Attach(SBAttachInfo &attach_info, |
581 | const SBDebugger &debugger, SBTarget &target, |
582 | SBError &error) { |
583 | LLDB_INSTRUMENT_VA(this, attach_info, debugger, target, error); |
584 | |
585 | if (PlatformSP platform_sp = GetSP()) { |
586 | if (platform_sp->IsConnected()) { |
587 | ProcessAttachInfo &info = attach_info.ref(); |
588 | Status status; |
589 | ProcessSP process_sp = platform_sp->Attach(attach_info&: info, debugger&: debugger.ref(), |
590 | target: target.GetSP().get(), error&: status); |
591 | error.SetError(status); |
592 | return SBProcess(process_sp); |
593 | } |
594 | |
595 | error.SetErrorString("not connected" ); |
596 | return {}; |
597 | } |
598 | |
599 | error.SetErrorString("invalid platform" ); |
600 | return {}; |
601 | } |
602 | |
603 | SBProcessInfoList SBPlatform::GetAllProcesses(SBError &error) { |
604 | if (PlatformSP platform_sp = GetSP()) { |
605 | if (platform_sp->IsConnected()) { |
606 | ProcessInstanceInfoList list = platform_sp->GetAllProcesses(); |
607 | return SBProcessInfoList(list); |
608 | } |
609 | error.SetErrorString("not connected" ); |
610 | return {}; |
611 | } |
612 | |
613 | error.SetErrorString("invalid platform" ); |
614 | return {}; |
615 | } |
616 | |
617 | SBError SBPlatform::Kill(const lldb::pid_t pid) { |
618 | LLDB_INSTRUMENT_VA(this, pid); |
619 | return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) { |
620 | return platform_sp->KillProcess(pid); |
621 | }); |
622 | } |
623 | |
624 | SBError SBPlatform::ExecuteConnected( |
625 | const std::function<Status(const lldb::PlatformSP &)> &func) { |
626 | SBError sb_error; |
627 | const auto platform_sp(GetSP()); |
628 | if (platform_sp) { |
629 | if (platform_sp->IsConnected()) |
630 | sb_error.ref() = func(platform_sp); |
631 | else |
632 | sb_error.SetErrorString("not connected" ); |
633 | } else |
634 | sb_error.SetErrorString("invalid platform" ); |
635 | |
636 | return sb_error; |
637 | } |
638 | |
639 | SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) { |
640 | LLDB_INSTRUMENT_VA(this, path, file_permissions); |
641 | |
642 | SBError sb_error; |
643 | PlatformSP platform_sp(GetSP()); |
644 | if (platform_sp) { |
645 | sb_error.ref() = |
646 | platform_sp->MakeDirectory(file_spec: FileSpec(path), permissions: file_permissions); |
647 | } else { |
648 | sb_error.SetErrorString("invalid platform" ); |
649 | } |
650 | return sb_error; |
651 | } |
652 | |
653 | uint32_t SBPlatform::GetFilePermissions(const char *path) { |
654 | LLDB_INSTRUMENT_VA(this, path); |
655 | |
656 | PlatformSP platform_sp(GetSP()); |
657 | if (platform_sp) { |
658 | uint32_t file_permissions = 0; |
659 | platform_sp->GetFilePermissions(file_spec: FileSpec(path), file_permissions); |
660 | return file_permissions; |
661 | } |
662 | return 0; |
663 | } |
664 | |
665 | SBError SBPlatform::SetFilePermissions(const char *path, |
666 | uint32_t file_permissions) { |
667 | LLDB_INSTRUMENT_VA(this, path, file_permissions); |
668 | |
669 | SBError sb_error; |
670 | PlatformSP platform_sp(GetSP()); |
671 | if (platform_sp) { |
672 | sb_error.ref() = |
673 | platform_sp->SetFilePermissions(file_spec: FileSpec(path), file_permissions); |
674 | } else { |
675 | sb_error.SetErrorString("invalid platform" ); |
676 | } |
677 | return sb_error; |
678 | } |
679 | |
680 | SBUnixSignals SBPlatform::GetUnixSignals() const { |
681 | LLDB_INSTRUMENT_VA(this); |
682 | |
683 | if (auto platform_sp = GetSP()) |
684 | return SBUnixSignals{platform_sp}; |
685 | |
686 | return SBUnixSignals(); |
687 | } |
688 | |
689 | SBEnvironment SBPlatform::GetEnvironment() { |
690 | LLDB_INSTRUMENT_VA(this); |
691 | PlatformSP platform_sp(GetSP()); |
692 | |
693 | if (platform_sp) { |
694 | return SBEnvironment(platform_sp->GetEnvironment()); |
695 | } |
696 | |
697 | return SBEnvironment(); |
698 | } |
699 | |
700 | SBError SBPlatform::SetLocateModuleCallback( |
701 | lldb::SBPlatformLocateModuleCallback callback, void *callback_baton) { |
702 | LLDB_INSTRUMENT_VA(this, callback, callback_baton); |
703 | PlatformSP platform_sp(GetSP()); |
704 | if (!platform_sp) |
705 | return SBError("invalid platform" ); |
706 | |
707 | if (!callback) { |
708 | // Clear the callback. |
709 | platform_sp->SetLocateModuleCallback(nullptr); |
710 | return SBError(); |
711 | } |
712 | |
713 | // Platform.h does not accept lldb::SBPlatformLocateModuleCallback directly |
714 | // because of the SBModuleSpec and SBFileSpec dependencies. Use a lambda to |
715 | // convert ModuleSpec/FileSpec <--> SBModuleSpec/SBFileSpec for the callback |
716 | // arguments. |
717 | platform_sp->SetLocateModuleCallback( |
718 | [callback, callback_baton](const ModuleSpec &module_spec, |
719 | FileSpec &module_file_spec, |
720 | FileSpec &symbol_file_spec) { |
721 | SBModuleSpec module_spec_sb(module_spec); |
722 | SBFileSpec module_file_spec_sb; |
723 | SBFileSpec symbol_file_spec_sb; |
724 | |
725 | SBError error = callback(callback_baton, module_spec_sb, |
726 | module_file_spec_sb, symbol_file_spec_sb); |
727 | |
728 | if (error.Success()) { |
729 | module_file_spec = module_file_spec_sb.ref(); |
730 | symbol_file_spec = symbol_file_spec_sb.ref(); |
731 | } |
732 | |
733 | return error.ref(); |
734 | }); |
735 | return SBError(); |
736 | } |
737 | |