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