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