1 //===-- SBLaunchInfo.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/SBLaunchInfo.h"
10 #include "SBReproducerPrivate.h"
11 
12 #include "lldb/API/SBEnvironment.h"
13 #include "lldb/API/SBError.h"
14 #include "lldb/API/SBFileSpec.h"
15 #include "lldb/API/SBListener.h"
16 #include "lldb/API/SBStream.h"
17 #include "lldb/API/SBStructuredData.h"
18 #include "lldb/Core/StructuredDataImpl.h"
19 #include "lldb/Host/ProcessLaunchInfo.h"
20 
21 using namespace lldb;
22 using namespace lldb_private;
23 
24 class lldb_private::SBLaunchInfoImpl : public ProcessLaunchInfo {
25 public:
26   SBLaunchInfoImpl() : m_envp(GetEnvironment().getEnvp()) {}
27 
28   const char *const *GetEnvp() const { return m_envp; }
29   void RegenerateEnvp() { m_envp = GetEnvironment().getEnvp(); }
30 
31   SBLaunchInfoImpl &operator=(const ProcessLaunchInfo &rhs) {
32     ProcessLaunchInfo::operator=(rhs);
33     RegenerateEnvp();
34     return *this;
35   }
36 
37 private:
38   Environment::Envp m_envp;
39 };
40 
41 SBLaunchInfo::SBLaunchInfo(const char **argv)
42     : m_opaque_sp(new SBLaunchInfoImpl()) {
43   LLDB_RECORD_CONSTRUCTOR(SBLaunchInfo, (const char **), argv);
44 
45   m_opaque_sp->GetFlags().Reset(eLaunchFlagDebug | eLaunchFlagDisableASLR);
46   if (argv && argv[0])
47     m_opaque_sp->GetArguments().SetArguments(argv);
48 }
49 
50 SBLaunchInfo::SBLaunchInfo(const SBLaunchInfo &rhs) {
51   LLDB_RECORD_CONSTRUCTOR(SBLaunchInfo, (const lldb::SBLaunchInfo &), rhs);
52 
53   m_opaque_sp = rhs.m_opaque_sp;
54 }
55 
56 SBLaunchInfo &SBLaunchInfo::operator=(const SBLaunchInfo &rhs) {
57   LLDB_RECORD_METHOD(SBLaunchInfo &,
58                      SBLaunchInfo, operator=,(const lldb::SBLaunchInfo &), rhs);
59 
60   m_opaque_sp = rhs.m_opaque_sp;
61   return LLDB_RECORD_RESULT(*this);
62 }
63 
64 SBLaunchInfo::~SBLaunchInfo() = default;
65 
66 const lldb_private::ProcessLaunchInfo &SBLaunchInfo::ref() const {
67   return *m_opaque_sp;
68 }
69 
70 void SBLaunchInfo::set_ref(const ProcessLaunchInfo &info) {
71   *m_opaque_sp = info;
72 }
73 
74 lldb::pid_t SBLaunchInfo::GetProcessID() {
75   LLDB_RECORD_METHOD_NO_ARGS(lldb::pid_t, SBLaunchInfo, GetProcessID);
76 
77   return m_opaque_sp->GetProcessID();
78 }
79 
80 uint32_t SBLaunchInfo::GetUserID() {
81   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBLaunchInfo, GetUserID);
82 
83   return m_opaque_sp->GetUserID();
84 }
85 
86 uint32_t SBLaunchInfo::GetGroupID() {
87   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBLaunchInfo, GetGroupID);
88 
89   return m_opaque_sp->GetGroupID();
90 }
91 
92 bool SBLaunchInfo::UserIDIsValid() {
93   LLDB_RECORD_METHOD_NO_ARGS(bool, SBLaunchInfo, UserIDIsValid);
94 
95   return m_opaque_sp->UserIDIsValid();
96 }
97 
98 bool SBLaunchInfo::GroupIDIsValid() {
99   LLDB_RECORD_METHOD_NO_ARGS(bool, SBLaunchInfo, GroupIDIsValid);
100 
101   return m_opaque_sp->GroupIDIsValid();
102 }
103 
104 void SBLaunchInfo::SetUserID(uint32_t uid) {
105   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetUserID, (uint32_t), uid);
106 
107   m_opaque_sp->SetUserID(uid);
108 }
109 
110 void SBLaunchInfo::SetGroupID(uint32_t gid) {
111   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetGroupID, (uint32_t), gid);
112 
113   m_opaque_sp->SetGroupID(gid);
114 }
115 
116 SBFileSpec SBLaunchInfo::GetExecutableFile() {
117   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFileSpec, SBLaunchInfo, GetExecutableFile);
118 
119   return LLDB_RECORD_RESULT(SBFileSpec(m_opaque_sp->GetExecutableFile()));
120 }
121 
122 void SBLaunchInfo::SetExecutableFile(SBFileSpec exe_file,
123                                      bool add_as_first_arg) {
124   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetExecutableFile,
125                      (lldb::SBFileSpec, bool), exe_file, add_as_first_arg);
126 
127   m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg);
128 }
129 
130 SBListener SBLaunchInfo::GetListener() {
131   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBListener, SBLaunchInfo, GetListener);
132 
133   return LLDB_RECORD_RESULT(SBListener(m_opaque_sp->GetListener()));
134 }
135 
136 void SBLaunchInfo::SetListener(SBListener &listener) {
137   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetListener, (lldb::SBListener &),
138                      listener);
139 
140   m_opaque_sp->SetListener(listener.GetSP());
141 }
142 
143 uint32_t SBLaunchInfo::GetNumArguments() {
144   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBLaunchInfo, GetNumArguments);
145 
146   return m_opaque_sp->GetArguments().GetArgumentCount();
147 }
148 
149 const char *SBLaunchInfo::GetArgumentAtIndex(uint32_t idx) {
150   LLDB_RECORD_METHOD(const char *, SBLaunchInfo, GetArgumentAtIndex, (uint32_t),
151                      idx);
152 
153   return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx);
154 }
155 
156 void SBLaunchInfo::SetArguments(const char **argv, bool append) {
157   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetArguments, (const char **, bool),
158                      argv, append);
159 
160   if (append) {
161     if (argv)
162       m_opaque_sp->GetArguments().AppendArguments(argv);
163   } else {
164     if (argv)
165       m_opaque_sp->GetArguments().SetArguments(argv);
166     else
167       m_opaque_sp->GetArguments().Clear();
168   }
169 }
170 
171 uint32_t SBLaunchInfo::GetNumEnvironmentEntries() {
172   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBLaunchInfo, GetNumEnvironmentEntries);
173 
174   return m_opaque_sp->GetEnvironment().size();
175 }
176 
177 const char *SBLaunchInfo::GetEnvironmentEntryAtIndex(uint32_t idx) {
178   LLDB_RECORD_METHOD(const char *, SBLaunchInfo, GetEnvironmentEntryAtIndex,
179                      (uint32_t), idx);
180 
181   if (idx > GetNumEnvironmentEntries())
182     return nullptr;
183   return m_opaque_sp->GetEnvp()[idx];
184 }
185 
186 void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) {
187   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetEnvironmentEntries,
188                      (const char **, bool), envp, append);
189   SetEnvironment(SBEnvironment(Environment(envp)), append);
190 }
191 
192 void SBLaunchInfo::SetEnvironment(const SBEnvironment &env, bool append) {
193   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetEnvironment,
194                      (const lldb::SBEnvironment &, bool), env, append);
195   Environment &refEnv = env.ref();
196   if (append) {
197     for (auto &KV : refEnv)
198       m_opaque_sp->GetEnvironment().insert_or_assign(KV.first(), KV.second);
199   } else
200     m_opaque_sp->GetEnvironment() = refEnv;
201   m_opaque_sp->RegenerateEnvp();
202 }
203 
204 SBEnvironment SBLaunchInfo::GetEnvironment() {
205   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBEnvironment, SBLaunchInfo, GetEnvironment);
206   return LLDB_RECORD_RESULT(
207       SBEnvironment(Environment(m_opaque_sp->GetEnvironment())));
208 }
209 
210 void SBLaunchInfo::Clear() {
211   LLDB_RECORD_METHOD_NO_ARGS(void, SBLaunchInfo, Clear);
212 
213   m_opaque_sp->Clear();
214 }
215 
216 const char *SBLaunchInfo::GetWorkingDirectory() const {
217   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBLaunchInfo,
218                                    GetWorkingDirectory);
219 
220   return m_opaque_sp->GetWorkingDirectory().GetCString();
221 }
222 
223 void SBLaunchInfo::SetWorkingDirectory(const char *working_dir) {
224   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetWorkingDirectory, (const char *),
225                      working_dir);
226 
227   m_opaque_sp->SetWorkingDirectory(FileSpec(working_dir));
228 }
229 
230 uint32_t SBLaunchInfo::GetLaunchFlags() {
231   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBLaunchInfo, GetLaunchFlags);
232 
233   return m_opaque_sp->GetFlags().Get();
234 }
235 
236 void SBLaunchInfo::SetLaunchFlags(uint32_t flags) {
237   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetLaunchFlags, (uint32_t), flags);
238 
239   m_opaque_sp->GetFlags().Reset(flags);
240 }
241 
242 const char *SBLaunchInfo::GetProcessPluginName() {
243   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBLaunchInfo, GetProcessPluginName);
244 
245   return m_opaque_sp->GetProcessPluginName();
246 }
247 
248 void SBLaunchInfo::SetProcessPluginName(const char *plugin_name) {
249   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetProcessPluginName, (const char *),
250                      plugin_name);
251 
252   return m_opaque_sp->SetProcessPluginName(plugin_name);
253 }
254 
255 const char *SBLaunchInfo::GetShell() {
256   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBLaunchInfo, GetShell);
257 
258   // Constify this string so that it is saved in the string pool.  Otherwise it
259   // would be freed when this function goes out of scope.
260   ConstString shell(m_opaque_sp->GetShell().GetPath().c_str());
261   return shell.AsCString();
262 }
263 
264 void SBLaunchInfo::SetShell(const char *path) {
265   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetShell, (const char *), path);
266 
267   m_opaque_sp->SetShell(FileSpec(path));
268 }
269 
270 bool SBLaunchInfo::GetShellExpandArguments() {
271   LLDB_RECORD_METHOD_NO_ARGS(bool, SBLaunchInfo, GetShellExpandArguments);
272 
273   return m_opaque_sp->GetShellExpandArguments();
274 }
275 
276 void SBLaunchInfo::SetShellExpandArguments(bool expand) {
277   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetShellExpandArguments, (bool),
278                      expand);
279 
280   m_opaque_sp->SetShellExpandArguments(expand);
281 }
282 
283 uint32_t SBLaunchInfo::GetResumeCount() {
284   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBLaunchInfo, GetResumeCount);
285 
286   return m_opaque_sp->GetResumeCount();
287 }
288 
289 void SBLaunchInfo::SetResumeCount(uint32_t c) {
290   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetResumeCount, (uint32_t), c);
291 
292   m_opaque_sp->SetResumeCount(c);
293 }
294 
295 bool SBLaunchInfo::AddCloseFileAction(int fd) {
296   LLDB_RECORD_METHOD(bool, SBLaunchInfo, AddCloseFileAction, (int), fd);
297 
298   return m_opaque_sp->AppendCloseFileAction(fd);
299 }
300 
301 bool SBLaunchInfo::AddDuplicateFileAction(int fd, int dup_fd) {
302   LLDB_RECORD_METHOD(bool, SBLaunchInfo, AddDuplicateFileAction, (int, int), fd,
303                      dup_fd);
304 
305   return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd);
306 }
307 
308 bool SBLaunchInfo::AddOpenFileAction(int fd, const char *path, bool read,
309                                      bool write) {
310   LLDB_RECORD_METHOD(bool, SBLaunchInfo, AddOpenFileAction,
311                      (int, const char *, bool, bool), fd, path, read, write);
312 
313   return m_opaque_sp->AppendOpenFileAction(fd, FileSpec(path), read, write);
314 }
315 
316 bool SBLaunchInfo::AddSuppressFileAction(int fd, bool read, bool write) {
317   LLDB_RECORD_METHOD(bool, SBLaunchInfo, AddSuppressFileAction,
318                      (int, bool, bool), fd, read, write);
319 
320   return m_opaque_sp->AppendSuppressFileAction(fd, read, write);
321 }
322 
323 void SBLaunchInfo::SetLaunchEventData(const char *data) {
324   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetLaunchEventData, (const char *),
325                      data);
326 
327   m_opaque_sp->SetLaunchEventData(data);
328 }
329 
330 const char *SBLaunchInfo::GetLaunchEventData() const {
331   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBLaunchInfo,
332                                    GetLaunchEventData);
333 
334   return m_opaque_sp->GetLaunchEventData();
335 }
336 
337 void SBLaunchInfo::SetDetachOnError(bool enable) {
338   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetDetachOnError, (bool), enable);
339 
340   m_opaque_sp->SetDetachOnError(enable);
341 }
342 
343 bool SBLaunchInfo::GetDetachOnError() const {
344   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBLaunchInfo, GetDetachOnError);
345 
346   return m_opaque_sp->GetDetachOnError();
347 }
348 
349 const char *SBLaunchInfo::GetScriptedProcessClassName() const {
350   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBLaunchInfo,
351                                    GetScriptedProcessClassName);
352 
353   // Constify this string so that it is saved in the string pool.  Otherwise it
354   // would be freed when this function goes out of scope.
355   ConstString class_name(m_opaque_sp->GetScriptedProcessClassName().c_str());
356   return class_name.AsCString();
357 }
358 
359 void SBLaunchInfo::SetScriptedProcessClassName(const char *class_name) {
360   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessClassName,
361                      (const char *), class_name);
362 
363   m_opaque_sp->SetScriptedProcessClassName(class_name);
364 }
365 
366 lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const {
367   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBStructuredData, SBLaunchInfo,
368                                    GetScriptedProcessDictionary);
369 
370   lldb_private::StructuredData::DictionarySP dict_sp =
371       m_opaque_sp->GetScriptedProcessDictionarySP();
372 
373   SBStructuredData data;
374   data.m_impl_up->SetObjectSP(dict_sp);
375 
376   return LLDB_RECORD_RESULT(data);
377 }
378 
379 void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) {
380   LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary,
381                      (lldb::SBStructuredData), dict);
382   if (!dict.IsValid() || !dict.m_impl_up)
383     return;
384 
385   StructuredData::ObjectSP obj_sp = dict.m_impl_up->GetObjectSP();
386 
387   if (!obj_sp)
388     return;
389 
390   StructuredData::DictionarySP dict_sp =
391       std::make_shared<StructuredData::Dictionary>(obj_sp);
392   if (!dict_sp || dict_sp->GetType() == lldb::eStructuredDataTypeInvalid)
393     return;
394 
395   m_opaque_sp->SetScriptedProcessDictionarySP(dict_sp);
396 }
397 
398 namespace lldb_private {
399 namespace repro {
400 
401 template <>
402 void RegisterMethods<SBLaunchInfo>(Registry &R) {
403   LLDB_REGISTER_CONSTRUCTOR(SBLaunchInfo, (const char **));
404   LLDB_REGISTER_CONSTRUCTOR(SBLaunchInfo, (const lldb::SBLaunchInfo &));
405   LLDB_REGISTER_METHOD(SBLaunchInfo &,
406                        SBLaunchInfo, operator=,(const lldb::SBLaunchInfo &));
407   LLDB_REGISTER_METHOD(lldb::pid_t, SBLaunchInfo, GetProcessID, ());
408   LLDB_REGISTER_METHOD(uint32_t, SBLaunchInfo, GetUserID, ());
409   LLDB_REGISTER_METHOD(uint32_t, SBLaunchInfo, GetGroupID, ());
410   LLDB_REGISTER_METHOD(bool, SBLaunchInfo, UserIDIsValid, ());
411   LLDB_REGISTER_METHOD(bool, SBLaunchInfo, GroupIDIsValid, ());
412   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetUserID, (uint32_t));
413   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetGroupID, (uint32_t));
414   LLDB_REGISTER_METHOD(lldb::SBFileSpec, SBLaunchInfo, GetExecutableFile, ());
415   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetExecutableFile,
416                        (lldb::SBFileSpec, bool));
417   LLDB_REGISTER_METHOD(lldb::SBListener, SBLaunchInfo, GetListener, ());
418   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetListener, (lldb::SBListener &));
419   LLDB_REGISTER_METHOD(uint32_t, SBLaunchInfo, GetNumArguments, ());
420   LLDB_REGISTER_METHOD(const char *, SBLaunchInfo, GetArgumentAtIndex,
421                        (uint32_t));
422   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetArguments,
423                        (const char **, bool));
424   LLDB_REGISTER_METHOD(uint32_t, SBLaunchInfo, GetNumEnvironmentEntries, ());
425   LLDB_REGISTER_METHOD(const char *, SBLaunchInfo, GetEnvironmentEntryAtIndex,
426                        (uint32_t));
427   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetEnvironmentEntries,
428                        (const char **, bool));
429   LLDB_REGISTER_METHOD(void, SBLaunchInfo, Clear, ());
430   LLDB_REGISTER_METHOD_CONST(const char *, SBLaunchInfo, GetWorkingDirectory,
431                              ());
432   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetWorkingDirectory,
433                        (const char *));
434   LLDB_REGISTER_METHOD(uint32_t, SBLaunchInfo, GetLaunchFlags, ());
435   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetLaunchFlags, (uint32_t));
436   LLDB_REGISTER_METHOD(const char *, SBLaunchInfo, GetProcessPluginName, ());
437   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetProcessPluginName,
438                        (const char *));
439   LLDB_REGISTER_METHOD(const char *, SBLaunchInfo, GetShell, ());
440   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetShell, (const char *));
441   LLDB_REGISTER_METHOD(bool, SBLaunchInfo, GetShellExpandArguments, ());
442   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetShellExpandArguments, (bool));
443   LLDB_REGISTER_METHOD(uint32_t, SBLaunchInfo, GetResumeCount, ());
444   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetResumeCount, (uint32_t));
445   LLDB_REGISTER_METHOD(bool, SBLaunchInfo, AddCloseFileAction, (int));
446   LLDB_REGISTER_METHOD(bool, SBLaunchInfo, AddDuplicateFileAction,
447                        (int, int));
448   LLDB_REGISTER_METHOD(bool, SBLaunchInfo, AddOpenFileAction,
449                        (int, const char *, bool, bool));
450   LLDB_REGISTER_METHOD(bool, SBLaunchInfo, AddSuppressFileAction,
451                        (int, bool, bool));
452   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetLaunchEventData,
453                        (const char *));
454   LLDB_REGISTER_METHOD_CONST(const char *, SBLaunchInfo, GetLaunchEventData,
455                              ());
456   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetDetachOnError, (bool));
457   LLDB_REGISTER_METHOD_CONST(bool, SBLaunchInfo, GetDetachOnError, ());
458   LLDB_REGISTER_METHOD_CONST(const char *, SBLaunchInfo,
459                              GetScriptedProcessClassName, ());
460   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetScriptedProcessClassName,
461                        (const char *));
462   LLDB_REGISTER_METHOD_CONST(lldb::SBStructuredData, SBLaunchInfo,
463                              GetScriptedProcessDictionary, ());
464   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary,
465                        (lldb::SBStructuredData));
466   LLDB_REGISTER_METHOD(void, SBLaunchInfo, SetEnvironment,
467                        (const lldb::SBEnvironment &, bool));
468   LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBLaunchInfo, GetEnvironment, ());
469 }
470 
471 }
472 }
473