| //===-- SBLaunchInfo.cpp --------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "lldb/API/SBLaunchInfo.h" | |
| #include "lldb/Utility/Instrumentation.h" | |
| #include "lldb/Utility/StringPool.h" | |
| #include "lldb/API/SBEnvironment.h" | |
| #include "lldb/API/SBError.h" | |
| #include "lldb/API/SBFileSpec.h" | |
| #include "lldb/API/SBListener.h" | |
| #include "lldb/API/SBStream.h" | |
| #include "lldb/API/SBStructuredData.h" | |
| #include "lldb/Core/StructuredDataImpl.h" | |
| #include "lldb/Host/ProcessLaunchInfo.h" | |
| #include "lldb/Utility/ConstString.h" | |
| #include "lldb/Utility/Listener.h" | |
| #include "lldb/Utility/ScriptedMetadata.h" | |
| using namespace lldb; | |
| using namespace lldb_private; | |
| class lldb_private::SBLaunchInfoImpl : public ProcessLaunchInfo { | |
| public: | |
| SBLaunchInfoImpl() : m_envp(GetEnvironment().getEnvp()) {} | |
| const char *const *GetEnvp() const { return m_envp; } | |
| void RegenerateEnvp() { m_envp = GetEnvironment().getEnvp(); } | |
| SBLaunchInfoImpl &operator=(const ProcessLaunchInfo &rhs) { | |
| ProcessLaunchInfo::operator=(rhs); | |
| RegenerateEnvp(); | |
| return *this; | |
| } | |
| private: | |
| Environment::Envp m_envp; | |
| }; | |
| SBLaunchInfo::SBLaunchInfo(const char **argv) | |
| : m_opaque_sp(new SBLaunchInfoImpl()) { | |
| LLDB_INSTRUMENT_VA(this, argv); | |
| m_opaque_sp->GetFlags().Reset(eLaunchFlagDebug | eLaunchFlagDisableASLR); | |
| if (argv && argv[0]) | |
| m_opaque_sp->GetArguments().SetArguments(argv); | |
| } | |
| SBLaunchInfo::SBLaunchInfo(const SBLaunchInfo &rhs) { | |
| LLDB_INSTRUMENT_VA(this, rhs); | |
| m_opaque_sp = rhs.m_opaque_sp; | |
| } | |
| SBLaunchInfo &SBLaunchInfo::operator=(const SBLaunchInfo &rhs) { | |
| LLDB_INSTRUMENT_VA(this, rhs); | |
| m_opaque_sp = rhs.m_opaque_sp; | |
| return *this; | |
| } | |
| SBLaunchInfo::~SBLaunchInfo() = default; | |
| const lldb_private::ProcessLaunchInfo &SBLaunchInfo::ref() const { | |
| return *m_opaque_sp; | |
| } | |
| void SBLaunchInfo::set_ref(const ProcessLaunchInfo &info) { | |
| *m_opaque_sp = info; | |
| } | |
| lldb::pid_t SBLaunchInfo::GetProcessID() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GetProcessID(); | |
| } | |
| uint32_t SBLaunchInfo::GetUserID() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GetUserID(); | |
| } | |
| uint32_t SBLaunchInfo::GetGroupID() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GetGroupID(); | |
| } | |
| bool SBLaunchInfo::UserIDIsValid() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->UserIDIsValid(); | |
| } | |
| bool SBLaunchInfo::GroupIDIsValid() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GroupIDIsValid(); | |
| } | |
| void SBLaunchInfo::SetUserID(uint32_t uid) { | |
| LLDB_INSTRUMENT_VA(this, uid); | |
| m_opaque_sp->SetUserID(uid); | |
| } | |
| void SBLaunchInfo::SetGroupID(uint32_t gid) { | |
| LLDB_INSTRUMENT_VA(this, gid); | |
| m_opaque_sp->SetGroupID(gid); | |
| } | |
| SBFileSpec SBLaunchInfo::GetExecutableFile() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return SBFileSpec(m_opaque_sp->GetExecutableFile()); | |
| } | |
| void SBLaunchInfo::SetExecutableFile(SBFileSpec exe_file, | |
| bool add_as_first_arg) { | |
| LLDB_INSTRUMENT_VA(this, exe_file, add_as_first_arg); | |
| m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg); | |
| } | |
| SBListener SBLaunchInfo::GetListener() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return SBListener(m_opaque_sp->GetListener()); | |
| } | |
| void SBLaunchInfo::SetListener(SBListener &listener) { | |
| LLDB_INSTRUMENT_VA(this, listener); | |
| m_opaque_sp->SetListener(listener.GetSP()); | |
| } | |
| uint32_t SBLaunchInfo::GetNumArguments() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GetArguments().GetArgumentCount(); | |
| } | |
| const char *SBLaunchInfo::GetArgumentAtIndex(uint32_t idx) { | |
| LLDB_INSTRUMENT_VA(this, idx); | |
| return StringPool::GetSystemPool().Intern( | |
| m_opaque_sp->GetArguments().GetArgumentAtIndex(idx)); | |
| } | |
| void SBLaunchInfo::SetArguments(const char **argv, bool append) { | |
| LLDB_INSTRUMENT_VA(this, argv, append); | |
| if (append) { | |
| if (argv) | |
| m_opaque_sp->GetArguments().AppendArguments(argv); | |
| } else { | |
| if (argv) | |
| m_opaque_sp->GetArguments().SetArguments(argv); | |
| else | |
| m_opaque_sp->GetArguments().Clear(); | |
| } | |
| } | |
| uint32_t SBLaunchInfo::GetNumEnvironmentEntries() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GetEnvironment().size(); | |
| } | |
| const char *SBLaunchInfo::GetEnvironmentEntryAtIndex(uint32_t idx) { | |
| LLDB_INSTRUMENT_VA(this, idx); | |
| if (idx > GetNumEnvironmentEntries()) | |
| return nullptr; | |
| return StringPool::GetSystemPool().Intern(m_opaque_sp->GetEnvp()[idx]); | |
| } | |
| void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) { | |
| LLDB_INSTRUMENT_VA(this, envp, append); | |
| SetEnvironment(SBEnvironment(Environment(envp)), append); | |
| } | |
| void SBLaunchInfo::SetEnvironment(const SBEnvironment &env, bool append) { | |
| LLDB_INSTRUMENT_VA(this, env, append); | |
| Environment &refEnv = env.ref(); | |
| if (append) { | |
| for (auto &KV : refEnv) | |
| m_opaque_sp->GetEnvironment().insert_or_assign(KV.first(), KV.second); | |
| } else | |
| m_opaque_sp->GetEnvironment() = refEnv; | |
| m_opaque_sp->RegenerateEnvp(); | |
| } | |
| SBEnvironment SBLaunchInfo::GetEnvironment() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return SBEnvironment(Environment(m_opaque_sp->GetEnvironment())); | |
| } | |
| void SBLaunchInfo::Clear() { | |
| LLDB_INSTRUMENT_VA(this); | |
| m_opaque_sp->Clear(); | |
| } | |
| const char *SBLaunchInfo::GetWorkingDirectory() const { | |
| LLDB_INSTRUMENT_VA(this); | |
| return StringPool::GetSystemPool().InternNonEmpty( | |
| m_opaque_sp->GetWorkingDirectory().GetPath()); | |
| } | |
| void SBLaunchInfo::SetWorkingDirectory(const char *working_dir) { | |
| LLDB_INSTRUMENT_VA(this, working_dir); | |
| m_opaque_sp->SetWorkingDirectory(FileSpec(working_dir)); | |
| } | |
| uint32_t SBLaunchInfo::GetLaunchFlags() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GetFlags().Get(); | |
| } | |
| void SBLaunchInfo::SetLaunchFlags(uint32_t flags) { | |
| LLDB_INSTRUMENT_VA(this, flags); | |
| m_opaque_sp->GetFlags().Reset(flags); | |
| } | |
| const char *SBLaunchInfo::GetProcessPluginName() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return StringPool::GetSystemPool().Intern( | |
| m_opaque_sp->GetProcessPluginName()); | |
| } | |
| void SBLaunchInfo::SetProcessPluginName(const char *plugin_name) { | |
| LLDB_INSTRUMENT_VA(this, plugin_name); | |
| return m_opaque_sp->SetProcessPluginName(plugin_name); | |
| } | |
| const char *SBLaunchInfo::GetShell() { | |
| LLDB_INSTRUMENT_VA(this); | |
| // Constify this string so that it is saved in the string pool. Otherwise it | |
| // would be freed when this function goes out of scope. | |
| ConstString shell(m_opaque_sp->GetShell().GetPath()); | |
| return shell.AsCString(nullptr); | |
| } | |
| void SBLaunchInfo::SetShell(const char *path) { | |
| LLDB_INSTRUMENT_VA(this, path); | |
| m_opaque_sp->SetShell(FileSpec(path)); | |
| } | |
| bool SBLaunchInfo::GetShellExpandArguments() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GetShellExpandArguments(); | |
| } | |
| void SBLaunchInfo::SetShellExpandArguments(bool expand) { | |
| LLDB_INSTRUMENT_VA(this, expand); | |
| m_opaque_sp->SetShellExpandArguments(expand); | |
| } | |
| uint32_t SBLaunchInfo::GetResumeCount() { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GetResumeCount(); | |
| } | |
| void SBLaunchInfo::SetResumeCount(uint32_t c) { | |
| LLDB_INSTRUMENT_VA(this, c); | |
| m_opaque_sp->SetResumeCount(c); | |
| } | |
| bool SBLaunchInfo::AddCloseFileAction(int fd) { | |
| LLDB_INSTRUMENT_VA(this, fd); | |
| return m_opaque_sp->AppendCloseFileAction(fd); | |
| } | |
| bool SBLaunchInfo::AddDuplicateFileAction(int fd, int dup_fd) { | |
| LLDB_INSTRUMENT_VA(this, fd, dup_fd); | |
| return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd); | |
| } | |
| bool SBLaunchInfo::AddOpenFileAction(int fd, const char *path, bool read, | |
| bool write) { | |
| LLDB_INSTRUMENT_VA(this, fd, path, read, write); | |
| return m_opaque_sp->AppendOpenFileAction(fd, FileSpec(path), read, write); | |
| } | |
| bool SBLaunchInfo::AddSuppressFileAction(int fd, bool read, bool write) { | |
| LLDB_INSTRUMENT_VA(this, fd, read, write); | |
| return m_opaque_sp->AppendSuppressFileAction(fd, read, write); | |
| } | |
| void SBLaunchInfo::SetLaunchEventData(const char *data) { | |
| LLDB_INSTRUMENT_VA(this, data); | |
| m_opaque_sp->SetLaunchEventData(data); | |
| } | |
| const char *SBLaunchInfo::GetLaunchEventData() const { | |
| LLDB_INSTRUMENT_VA(this); | |
| return StringPool::GetSystemPool().Intern(m_opaque_sp->GetLaunchEventData()); | |
| } | |
| void SBLaunchInfo::SetDetachOnError(bool enable) { | |
| LLDB_INSTRUMENT_VA(this, enable); | |
| m_opaque_sp->SetDetachOnError(enable); | |
| } | |
| bool SBLaunchInfo::GetDetachOnError() const { | |
| LLDB_INSTRUMENT_VA(this); | |
| return m_opaque_sp->GetDetachOnError(); | |
| } | |
| const char *SBLaunchInfo::GetScriptedProcessClassName() const { | |
| LLDB_INSTRUMENT_VA(this); | |
| ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); | |
| if (!metadata_sp || !*metadata_sp) | |
| return nullptr; | |
| // Constify this string so that it is saved in the string pool. Otherwise it | |
| // would be freed when this function goes out of scope. | |
| ConstString class_name(metadata_sp->GetClassName()); | |
| return class_name.AsCString(nullptr); | |
| } | |
| void SBLaunchInfo::SetScriptedProcessClassName(const char *class_name) { | |
| LLDB_INSTRUMENT_VA(this, class_name); | |
| ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); | |
| StructuredData::DictionarySP dict_sp = | |
| metadata_sp ? metadata_sp->GetArgsSP() : nullptr; | |
| metadata_sp = std::make_shared<ScriptedMetadata>(class_name, dict_sp); | |
| m_opaque_sp->SetScriptedMetadata(metadata_sp); | |
| } | |
| lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const { | |
| LLDB_INSTRUMENT_VA(this); | |
| ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); | |
| SBStructuredData data; | |
| if (!metadata_sp) | |
| return data; | |
| lldb_private::StructuredData::DictionarySP dict_sp = metadata_sp->GetArgsSP(); | |
| data.m_impl_up->SetObjectSP(dict_sp); | |
| return data; | |
| } | |
| void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) { | |
| LLDB_INSTRUMENT_VA(this, dict); | |
| if (!dict.IsValid() || !dict.m_impl_up) | |
| return; | |
| StructuredData::ObjectSP obj_sp = dict.m_impl_up->GetObjectSP(); | |
| if (!obj_sp) | |
| return; | |
| StructuredData::DictionarySP dict_sp = | |
| std::make_shared<StructuredData::Dictionary>(obj_sp); | |
| if (!dict_sp || dict_sp->GetType() == lldb::eStructuredDataTypeInvalid) | |
| return; | |
| ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); | |
| llvm::StringRef class_name = metadata_sp ? metadata_sp->GetClassName() : ""; | |
| metadata_sp = std::make_shared<ScriptedMetadata>(class_name, dict_sp); | |
| m_opaque_sp->SetScriptedMetadata(metadata_sp); | |
| } | |
| SBListener SBLaunchInfo::GetShadowListener() { | |
| LLDB_INSTRUMENT_VA(this); | |
| lldb::ListenerSP shadow_sp = m_opaque_sp->GetShadowListener(); | |
| if (!shadow_sp) | |
| return SBListener(); | |
| return SBListener(shadow_sp); | |
| } | |
| void SBLaunchInfo::SetShadowListener(SBListener &listener) { | |
| LLDB_INSTRUMENT_VA(this, listener); | |
| m_opaque_sp->SetShadowListener(listener.GetSP()); | |
| } |