1 //===-- SBAttachInfo.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/SBAttachInfo.h"
10 #include "Utils.h"
11 #include "lldb/API/SBFileSpec.h"
12 #include "lldb/API/SBListener.h"
13 #include "lldb/API/SBStructuredData.h"
14 #include "lldb/Target/Process.h"
15 #include "lldb/Utility/Instrumentation.h"
16 #include "lldb/Utility/ScriptedMetadata.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 SBAttachInfo::SBAttachInfo() : m_opaque_sp(new ProcessAttachInfo()) {
22   LLDB_INSTRUMENT_VA(this);
23 }
24 
25 SBAttachInfo::SBAttachInfo(lldb::pid_t pid)
26     : m_opaque_sp(new ProcessAttachInfo()) {
27   LLDB_INSTRUMENT_VA(this, pid);
28 
29   m_opaque_sp->SetProcessID(pid);
30 }
31 
32 SBAttachInfo::SBAttachInfo(const char *path, bool wait_for)
33     : m_opaque_sp(new ProcessAttachInfo()) {
34   LLDB_INSTRUMENT_VA(this, path, wait_for);
35 
36   if (path && path[0])
37     m_opaque_sp->GetExecutableFile().SetFile(path, FileSpec::Style::native);
38   m_opaque_sp->SetWaitForLaunch(wait_for);
39 }
40 
41 SBAttachInfo::SBAttachInfo(const char *path, bool wait_for, bool async)
42     : m_opaque_sp(new ProcessAttachInfo()) {
43   LLDB_INSTRUMENT_VA(this, path, wait_for, async);
44 
45   if (path && path[0])
46     m_opaque_sp->GetExecutableFile().SetFile(path, FileSpec::Style::native);
47   m_opaque_sp->SetWaitForLaunch(wait_for);
48   m_opaque_sp->SetAsync(async);
49 }
50 
51 SBAttachInfo::SBAttachInfo(const SBAttachInfo &rhs)
52     : m_opaque_sp(new ProcessAttachInfo()) {
53   LLDB_INSTRUMENT_VA(this, rhs);
54 
55   m_opaque_sp = clone(rhs.m_opaque_sp);
56 }
57 
58 SBAttachInfo::~SBAttachInfo() = default;
59 
60 lldb_private::ProcessAttachInfo &SBAttachInfo::ref() { return *m_opaque_sp; }
61 
62 SBAttachInfo &SBAttachInfo::operator=(const SBAttachInfo &rhs) {
63   LLDB_INSTRUMENT_VA(this, rhs);
64 
65   if (this != &rhs)
66     m_opaque_sp = clone(rhs.m_opaque_sp);
67   return *this;
68 }
69 
70 lldb::pid_t SBAttachInfo::GetProcessID() {
71   LLDB_INSTRUMENT_VA(this);
72 
73   return m_opaque_sp->GetProcessID();
74 }
75 
76 void SBAttachInfo::SetProcessID(lldb::pid_t pid) {
77   LLDB_INSTRUMENT_VA(this, pid);
78 
79   m_opaque_sp->SetProcessID(pid);
80 }
81 
82 uint32_t SBAttachInfo::GetResumeCount() {
83   LLDB_INSTRUMENT_VA(this);
84 
85   return m_opaque_sp->GetResumeCount();
86 }
87 
88 void SBAttachInfo::SetResumeCount(uint32_t c) {
89   LLDB_INSTRUMENT_VA(this, c);
90 
91   m_opaque_sp->SetResumeCount(c);
92 }
93 
94 const char *SBAttachInfo::GetProcessPluginName() {
95   LLDB_INSTRUMENT_VA(this);
96 
97   return ConstString(m_opaque_sp->GetProcessPluginName()).GetCString();
98 }
99 
100 void SBAttachInfo::SetProcessPluginName(const char *plugin_name) {
101   LLDB_INSTRUMENT_VA(this, plugin_name);
102 
103   return m_opaque_sp->SetProcessPluginName(plugin_name);
104 }
105 
106 void SBAttachInfo::SetExecutable(const char *path) {
107   LLDB_INSTRUMENT_VA(this, path);
108 
109   if (path && path[0])
110     m_opaque_sp->GetExecutableFile().SetFile(path, FileSpec::Style::native);
111   else
112     m_opaque_sp->GetExecutableFile().Clear();
113 }
114 
115 void SBAttachInfo::SetExecutable(SBFileSpec exe_file) {
116   LLDB_INSTRUMENT_VA(this, exe_file);
117 
118   if (exe_file.IsValid())
119     m_opaque_sp->GetExecutableFile() = exe_file.ref();
120   else
121     m_opaque_sp->GetExecutableFile().Clear();
122 }
123 
124 bool SBAttachInfo::GetWaitForLaunch() {
125   LLDB_INSTRUMENT_VA(this);
126 
127   return m_opaque_sp->GetWaitForLaunch();
128 }
129 
130 void SBAttachInfo::SetWaitForLaunch(bool b) {
131   LLDB_INSTRUMENT_VA(this, b);
132 
133   m_opaque_sp->SetWaitForLaunch(b);
134 }
135 
136 void SBAttachInfo::SetWaitForLaunch(bool b, bool async) {
137   LLDB_INSTRUMENT_VA(this, b, async);
138 
139   m_opaque_sp->SetWaitForLaunch(b);
140   m_opaque_sp->SetAsync(async);
141 }
142 
143 bool SBAttachInfo::GetIgnoreExisting() {
144   LLDB_INSTRUMENT_VA(this);
145 
146   return m_opaque_sp->GetIgnoreExisting();
147 }
148 
149 void SBAttachInfo::SetIgnoreExisting(bool b) {
150   LLDB_INSTRUMENT_VA(this, b);
151 
152   m_opaque_sp->SetIgnoreExisting(b);
153 }
154 
155 uint32_t SBAttachInfo::GetUserID() {
156   LLDB_INSTRUMENT_VA(this);
157 
158   return m_opaque_sp->GetUserID();
159 }
160 
161 uint32_t SBAttachInfo::GetGroupID() {
162   LLDB_INSTRUMENT_VA(this);
163 
164   return m_opaque_sp->GetGroupID();
165 }
166 
167 bool SBAttachInfo::UserIDIsValid() {
168   LLDB_INSTRUMENT_VA(this);
169 
170   return m_opaque_sp->UserIDIsValid();
171 }
172 
173 bool SBAttachInfo::GroupIDIsValid() {
174   LLDB_INSTRUMENT_VA(this);
175 
176   return m_opaque_sp->GroupIDIsValid();
177 }
178 
179 void SBAttachInfo::SetUserID(uint32_t uid) {
180   LLDB_INSTRUMENT_VA(this, uid);
181 
182   m_opaque_sp->SetUserID(uid);
183 }
184 
185 void SBAttachInfo::SetGroupID(uint32_t gid) {
186   LLDB_INSTRUMENT_VA(this, gid);
187 
188   m_opaque_sp->SetGroupID(gid);
189 }
190 
191 uint32_t SBAttachInfo::GetEffectiveUserID() {
192   LLDB_INSTRUMENT_VA(this);
193 
194   return m_opaque_sp->GetEffectiveUserID();
195 }
196 
197 uint32_t SBAttachInfo::GetEffectiveGroupID() {
198   LLDB_INSTRUMENT_VA(this);
199 
200   return m_opaque_sp->GetEffectiveGroupID();
201 }
202 
203 bool SBAttachInfo::EffectiveUserIDIsValid() {
204   LLDB_INSTRUMENT_VA(this);
205 
206   return m_opaque_sp->EffectiveUserIDIsValid();
207 }
208 
209 bool SBAttachInfo::EffectiveGroupIDIsValid() {
210   LLDB_INSTRUMENT_VA(this);
211 
212   return m_opaque_sp->EffectiveGroupIDIsValid();
213 }
214 
215 void SBAttachInfo::SetEffectiveUserID(uint32_t uid) {
216   LLDB_INSTRUMENT_VA(this, uid);
217 
218   m_opaque_sp->SetEffectiveUserID(uid);
219 }
220 
221 void SBAttachInfo::SetEffectiveGroupID(uint32_t gid) {
222   LLDB_INSTRUMENT_VA(this, gid);
223 
224   m_opaque_sp->SetEffectiveGroupID(gid);
225 }
226 
227 lldb::pid_t SBAttachInfo::GetParentProcessID() {
228   LLDB_INSTRUMENT_VA(this);
229 
230   return m_opaque_sp->GetParentProcessID();
231 }
232 
233 void SBAttachInfo::SetParentProcessID(lldb::pid_t pid) {
234   LLDB_INSTRUMENT_VA(this, pid);
235 
236   m_opaque_sp->SetParentProcessID(pid);
237 }
238 
239 bool SBAttachInfo::ParentProcessIDIsValid() {
240   LLDB_INSTRUMENT_VA(this);
241 
242   return m_opaque_sp->ParentProcessIDIsValid();
243 }
244 
245 SBListener SBAttachInfo::GetListener() {
246   LLDB_INSTRUMENT_VA(this);
247 
248   return SBListener(m_opaque_sp->GetListener());
249 }
250 
251 void SBAttachInfo::SetListener(SBListener &listener) {
252   LLDB_INSTRUMENT_VA(this, listener);
253 
254   m_opaque_sp->SetListener(listener.GetSP());
255 }
256 
257 SBListener SBAttachInfo::GetShadowListener() {
258   LLDB_INSTRUMENT_VA(this);
259 
260   lldb::ListenerSP shadow_sp = m_opaque_sp->GetShadowListener();
261   if (!shadow_sp)
262     return SBListener();
263   return SBListener(shadow_sp);
264 }
265 
266 void SBAttachInfo::SetShadowListener(SBListener &listener) {
267   LLDB_INSTRUMENT_VA(this, listener);
268 
269   ListenerSP listener_sp = listener.GetSP();
270   if (listener_sp && listener.IsValid())
271     listener_sp->SetShadow(true);
272   else
273     listener_sp = nullptr;
274 
275   m_opaque_sp->SetShadowListener(listener_sp);
276 }
277 
278 const char *SBAttachInfo::GetScriptedProcessClassName() const {
279   LLDB_INSTRUMENT_VA(this);
280 
281   ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata();
282 
283   if (!metadata_sp || !*metadata_sp)
284     return nullptr;
285 
286   // Constify this string so that it is saved in the string pool.  Otherwise it
287   // would be freed when this function goes out of scope.
288   ConstString class_name(metadata_sp->GetClassName().data());
289   return class_name.AsCString();
290 }
291 
292 void SBAttachInfo::SetScriptedProcessClassName(const char *class_name) {
293   LLDB_INSTRUMENT_VA(this, class_name);
294 
295   ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata();
296 
297   if (!metadata_sp)
298     metadata_sp = std::make_shared<ScriptedMetadata>(class_name, nullptr);
299   else
300     metadata_sp = std::make_shared<ScriptedMetadata>(class_name,
301                                                      metadata_sp->GetArgsSP());
302 
303   m_opaque_sp->SetScriptedMetadata(metadata_sp);
304 }
305 
306 lldb::SBStructuredData SBAttachInfo::GetScriptedProcessDictionary() const {
307   LLDB_INSTRUMENT_VA(this);
308 
309   ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata();
310 
311   SBStructuredData data;
312   if (!metadata_sp)
313     return data;
314 
315   lldb_private::StructuredData::DictionarySP dict_sp = metadata_sp->GetArgsSP();
316   data.m_impl_up->SetObjectSP(dict_sp);
317 
318   return data;
319 }
320 
321 void SBAttachInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) {
322   LLDB_INSTRUMENT_VA(this, dict);
323 
324   if (!dict.IsValid() || !dict.m_impl_up)
325     return;
326 
327   StructuredData::ObjectSP obj_sp = dict.m_impl_up->GetObjectSP();
328 
329   if (!obj_sp)
330     return;
331 
332   StructuredData::DictionarySP dict_sp =
333       std::make_shared<StructuredData::Dictionary>(obj_sp);
334   if (!dict_sp || dict_sp->GetType() == lldb::eStructuredDataTypeInvalid)
335     return;
336 
337   ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata();
338 
339   if (!metadata_sp)
340     metadata_sp = std::make_shared<ScriptedMetadata>("", dict_sp);
341   else
342     metadata_sp = std::make_shared<ScriptedMetadata>(
343         metadata_sp->GetClassName(), dict_sp);
344 
345   m_opaque_sp->SetScriptedMetadata(metadata_sp);
346 }
347