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 "lldb/Utility/Instrumentation.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_INSTRUMENT_VA(this, 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_INSTRUMENT_VA(this, rhs);
52 
53   m_opaque_sp = rhs.m_opaque_sp;
54 }
55 
56 SBLaunchInfo &SBLaunchInfo::operator=(const SBLaunchInfo &rhs) {
57   LLDB_INSTRUMENT_VA(this, rhs);
58 
59   m_opaque_sp = rhs.m_opaque_sp;
60   return *this;
61 }
62 
63 SBLaunchInfo::~SBLaunchInfo() = default;
64 
65 const lldb_private::ProcessLaunchInfo &SBLaunchInfo::ref() const {
66   return *m_opaque_sp;
67 }
68 
69 void SBLaunchInfo::set_ref(const ProcessLaunchInfo &info) {
70   *m_opaque_sp = info;
71 }
72 
73 lldb::pid_t SBLaunchInfo::GetProcessID() {
74   LLDB_INSTRUMENT_VA(this);
75 
76   return m_opaque_sp->GetProcessID();
77 }
78 
79 uint32_t SBLaunchInfo::GetUserID() {
80   LLDB_INSTRUMENT_VA(this);
81 
82   return m_opaque_sp->GetUserID();
83 }
84 
85 uint32_t SBLaunchInfo::GetGroupID() {
86   LLDB_INSTRUMENT_VA(this);
87 
88   return m_opaque_sp->GetGroupID();
89 }
90 
91 bool SBLaunchInfo::UserIDIsValid() {
92   LLDB_INSTRUMENT_VA(this);
93 
94   return m_opaque_sp->UserIDIsValid();
95 }
96 
97 bool SBLaunchInfo::GroupIDIsValid() {
98   LLDB_INSTRUMENT_VA(this);
99 
100   return m_opaque_sp->GroupIDIsValid();
101 }
102 
103 void SBLaunchInfo::SetUserID(uint32_t uid) {
104   LLDB_INSTRUMENT_VA(this, uid);
105 
106   m_opaque_sp->SetUserID(uid);
107 }
108 
109 void SBLaunchInfo::SetGroupID(uint32_t gid) {
110   LLDB_INSTRUMENT_VA(this, gid);
111 
112   m_opaque_sp->SetGroupID(gid);
113 }
114 
115 SBFileSpec SBLaunchInfo::GetExecutableFile() {
116   LLDB_INSTRUMENT_VA(this);
117 
118   return SBFileSpec(m_opaque_sp->GetExecutableFile());
119 }
120 
121 void SBLaunchInfo::SetExecutableFile(SBFileSpec exe_file,
122                                      bool add_as_first_arg) {
123   LLDB_INSTRUMENT_VA(this, exe_file, add_as_first_arg);
124 
125   m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg);
126 }
127 
128 SBListener SBLaunchInfo::GetListener() {
129   LLDB_INSTRUMENT_VA(this);
130 
131   return SBListener(m_opaque_sp->GetListener());
132 }
133 
134 void SBLaunchInfo::SetListener(SBListener &listener) {
135   LLDB_INSTRUMENT_VA(this, listener);
136 
137   m_opaque_sp->SetListener(listener.GetSP());
138 }
139 
140 uint32_t SBLaunchInfo::GetNumArguments() {
141   LLDB_INSTRUMENT_VA(this);
142 
143   return m_opaque_sp->GetArguments().GetArgumentCount();
144 }
145 
146 const char *SBLaunchInfo::GetArgumentAtIndex(uint32_t idx) {
147   LLDB_INSTRUMENT_VA(this, idx);
148 
149   return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx);
150 }
151 
152 void SBLaunchInfo::SetArguments(const char **argv, bool append) {
153   LLDB_INSTRUMENT_VA(this, argv, append);
154 
155   if (append) {
156     if (argv)
157       m_opaque_sp->GetArguments().AppendArguments(argv);
158   } else {
159     if (argv)
160       m_opaque_sp->GetArguments().SetArguments(argv);
161     else
162       m_opaque_sp->GetArguments().Clear();
163   }
164 }
165 
166 uint32_t SBLaunchInfo::GetNumEnvironmentEntries() {
167   LLDB_INSTRUMENT_VA(this);
168 
169   return m_opaque_sp->GetEnvironment().size();
170 }
171 
172 const char *SBLaunchInfo::GetEnvironmentEntryAtIndex(uint32_t idx) {
173   LLDB_INSTRUMENT_VA(this, idx);
174 
175   if (idx > GetNumEnvironmentEntries())
176     return nullptr;
177   return m_opaque_sp->GetEnvp()[idx];
178 }
179 
180 void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) {
181   LLDB_INSTRUMENT_VA(this, envp, append);
182   SetEnvironment(SBEnvironment(Environment(envp)), append);
183 }
184 
185 void SBLaunchInfo::SetEnvironment(const SBEnvironment &env, bool append) {
186   LLDB_INSTRUMENT_VA(this, env, append);
187   Environment &refEnv = env.ref();
188   if (append) {
189     for (auto &KV : refEnv)
190       m_opaque_sp->GetEnvironment().insert_or_assign(KV.first(), KV.second);
191   } else
192     m_opaque_sp->GetEnvironment() = refEnv;
193   m_opaque_sp->RegenerateEnvp();
194 }
195 
196 SBEnvironment SBLaunchInfo::GetEnvironment() {
197   LLDB_INSTRUMENT_VA(this);
198   return SBEnvironment(Environment(m_opaque_sp->GetEnvironment()));
199 }
200 
201 void SBLaunchInfo::Clear() {
202   LLDB_INSTRUMENT_VA(this);
203 
204   m_opaque_sp->Clear();
205 }
206 
207 const char *SBLaunchInfo::GetWorkingDirectory() const {
208   LLDB_INSTRUMENT_VA(this);
209 
210   return m_opaque_sp->GetWorkingDirectory().GetCString();
211 }
212 
213 void SBLaunchInfo::SetWorkingDirectory(const char *working_dir) {
214   LLDB_INSTRUMENT_VA(this, working_dir);
215 
216   m_opaque_sp->SetWorkingDirectory(FileSpec(working_dir));
217 }
218 
219 uint32_t SBLaunchInfo::GetLaunchFlags() {
220   LLDB_INSTRUMENT_VA(this);
221 
222   return m_opaque_sp->GetFlags().Get();
223 }
224 
225 void SBLaunchInfo::SetLaunchFlags(uint32_t flags) {
226   LLDB_INSTRUMENT_VA(this, flags);
227 
228   m_opaque_sp->GetFlags().Reset(flags);
229 }
230 
231 const char *SBLaunchInfo::GetProcessPluginName() {
232   LLDB_INSTRUMENT_VA(this);
233 
234   return m_opaque_sp->GetProcessPluginName();
235 }
236 
237 void SBLaunchInfo::SetProcessPluginName(const char *plugin_name) {
238   LLDB_INSTRUMENT_VA(this, plugin_name);
239 
240   return m_opaque_sp->SetProcessPluginName(plugin_name);
241 }
242 
243 const char *SBLaunchInfo::GetShell() {
244   LLDB_INSTRUMENT_VA(this);
245 
246   // Constify this string so that it is saved in the string pool.  Otherwise it
247   // would be freed when this function goes out of scope.
248   ConstString shell(m_opaque_sp->GetShell().GetPath().c_str());
249   return shell.AsCString();
250 }
251 
252 void SBLaunchInfo::SetShell(const char *path) {
253   LLDB_INSTRUMENT_VA(this, path);
254 
255   m_opaque_sp->SetShell(FileSpec(path));
256 }
257 
258 bool SBLaunchInfo::GetShellExpandArguments() {
259   LLDB_INSTRUMENT_VA(this);
260 
261   return m_opaque_sp->GetShellExpandArguments();
262 }
263 
264 void SBLaunchInfo::SetShellExpandArguments(bool expand) {
265   LLDB_INSTRUMENT_VA(this, expand);
266 
267   m_opaque_sp->SetShellExpandArguments(expand);
268 }
269 
270 uint32_t SBLaunchInfo::GetResumeCount() {
271   LLDB_INSTRUMENT_VA(this);
272 
273   return m_opaque_sp->GetResumeCount();
274 }
275 
276 void SBLaunchInfo::SetResumeCount(uint32_t c) {
277   LLDB_INSTRUMENT_VA(this, c);
278 
279   m_opaque_sp->SetResumeCount(c);
280 }
281 
282 bool SBLaunchInfo::AddCloseFileAction(int fd) {
283   LLDB_INSTRUMENT_VA(this, fd);
284 
285   return m_opaque_sp->AppendCloseFileAction(fd);
286 }
287 
288 bool SBLaunchInfo::AddDuplicateFileAction(int fd, int dup_fd) {
289   LLDB_INSTRUMENT_VA(this, fd, dup_fd);
290 
291   return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd);
292 }
293 
294 bool SBLaunchInfo::AddOpenFileAction(int fd, const char *path, bool read,
295                                      bool write) {
296   LLDB_INSTRUMENT_VA(this, fd, path, read, write);
297 
298   return m_opaque_sp->AppendOpenFileAction(fd, FileSpec(path), read, write);
299 }
300 
301 bool SBLaunchInfo::AddSuppressFileAction(int fd, bool read, bool write) {
302   LLDB_INSTRUMENT_VA(this, fd, read, write);
303 
304   return m_opaque_sp->AppendSuppressFileAction(fd, read, write);
305 }
306 
307 void SBLaunchInfo::SetLaunchEventData(const char *data) {
308   LLDB_INSTRUMENT_VA(this, data);
309 
310   m_opaque_sp->SetLaunchEventData(data);
311 }
312 
313 const char *SBLaunchInfo::GetLaunchEventData() const {
314   LLDB_INSTRUMENT_VA(this);
315 
316   return m_opaque_sp->GetLaunchEventData();
317 }
318 
319 void SBLaunchInfo::SetDetachOnError(bool enable) {
320   LLDB_INSTRUMENT_VA(this, enable);
321 
322   m_opaque_sp->SetDetachOnError(enable);
323 }
324 
325 bool SBLaunchInfo::GetDetachOnError() const {
326   LLDB_INSTRUMENT_VA(this);
327 
328   return m_opaque_sp->GetDetachOnError();
329 }
330 
331 const char *SBLaunchInfo::GetScriptedProcessClassName() const {
332   LLDB_INSTRUMENT_VA(this);
333 
334   // Constify this string so that it is saved in the string pool.  Otherwise it
335   // would be freed when this function goes out of scope.
336   ConstString class_name(m_opaque_sp->GetScriptedProcessClassName().c_str());
337   return class_name.AsCString();
338 }
339 
340 void SBLaunchInfo::SetScriptedProcessClassName(const char *class_name) {
341   LLDB_INSTRUMENT_VA(this, class_name);
342 
343   m_opaque_sp->SetScriptedProcessClassName(class_name);
344 }
345 
346 lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const {
347   LLDB_INSTRUMENT_VA(this);
348 
349   lldb_private::StructuredData::DictionarySP dict_sp =
350       m_opaque_sp->GetScriptedProcessDictionarySP();
351 
352   SBStructuredData data;
353   data.m_impl_up->SetObjectSP(dict_sp);
354 
355   return data;
356 }
357 
358 void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) {
359   LLDB_INSTRUMENT_VA(this, dict);
360   if (!dict.IsValid() || !dict.m_impl_up)
361     return;
362 
363   StructuredData::ObjectSP obj_sp = dict.m_impl_up->GetObjectSP();
364 
365   if (!obj_sp)
366     return;
367 
368   StructuredData::DictionarySP dict_sp =
369       std::make_shared<StructuredData::Dictionary>(obj_sp);
370   if (!dict_sp || dict_sp->GetType() == lldb::eStructuredDataTypeInvalid)
371     return;
372 
373   m_opaque_sp->SetScriptedProcessDictionarySP(dict_sp);
374 }
375