mib created this revision.
mib added reviewers: JDevlieghere, jingham, labath.
mib added a project: LLDB.
Herald added a subscriber: emaste.
Herald added a project: All.
mib requested review of this revision.
Herald added a subscriber: lldb-commits.

This patch is preparatory work for Scripted Platform support and does
multiple things:

First, it introduces new options for the `platform select` command and
`SBPlatform::Create` API, to hold a reference to the debugger object,
the name of the python script managing the Scripted Platform and a
structured data dictionary that the user can use to pass arbitrary data.

Then, it updates the various `Create` and `GetOrCreate` methods for
the `Platform` and `PlatformList` classes to pass down the new parameter
to the `Platform::CreateInstance` callbacks.

Finally, it updates every callback to reflect these changes.

Signed-off-by: Med Ismail Bennani <medismail.benn...@gmail.com>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D139249

Files:
  lldb/bindings/interface/SBPlatform.i
  lldb/include/lldb/API/SBDebugger.h
  lldb/include/lldb/API/SBPlatform.h
  lldb/include/lldb/API/SBStructuredData.h
  lldb/include/lldb/Interpreter/OptionGroupPlatform.h
  lldb/include/lldb/Target/Platform.h
  lldb/include/lldb/lldb-private-interfaces.h
  lldb/source/API/SBDebugger.cpp
  lldb/source/API/SBPlatform.cpp
  lldb/source/Commands/CommandObjectPlatform.cpp
  lldb/source/Commands/CommandObjectPlatform.h
  lldb/source/Core/Debugger.cpp
  lldb/source/Interpreter/OptionGroupPlatform.cpp
  lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
  lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
  lldb/source/Plugins/Platform/Android/PlatformAndroid.h
  lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
  lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
  lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
  lldb/source/Plugins/Platform/Linux/PlatformLinux.h
  lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
  lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
  lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
  lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
  lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
  lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
  lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
  lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
  lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
  lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
  lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
  lldb/source/Plugins/Platform/Windows/PlatformWindows.h
  lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
  lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
  lldb/source/Target/Platform.cpp
  lldb/source/Target/Process.cpp
  lldb/source/Target/Target.cpp
  lldb/source/Target/TargetList.cpp
  lldb/unittests/Platform/PlatformTest.cpp

Index: lldb/unittests/Platform/PlatformTest.cpp
===================================================================
--- lldb/unittests/Platform/PlatformTest.cpp
+++ lldb/unittests/Platform/PlatformTest.cpp
@@ -59,7 +59,9 @@
     PluginManager::UnregisterPlugin(PlatformThumb::CreateInstance);
   }
 
-  static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
+  static PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                   const Debugger *debugger,
+                                   const ScriptedMetadata *metadata) {
     return std::make_shared<PlatformThumb>();
   }
 
Index: lldb/source/Target/TargetList.cpp
===================================================================
--- lldb/source/Target/TargetList.cpp
+++ lldb/source/Target/TargetList.cpp
@@ -185,7 +185,7 @@
         for (const ModuleSpec &spec : module_specs.ModuleSpecs())
           archs.push_back(spec.GetArchitecture());
         if (PlatformSP platform_for_archs_sp =
-                platform_list.GetOrCreate(archs, {}, candidates)) {
+                platform_list.GetOrCreate(archs, {}, candidates, nullptr)) {
           platform_sp = platform_for_archs_sp;
         } else if (candidates.empty()) {
           error.SetErrorString("no matching platforms found for this file");
@@ -218,7 +218,8 @@
   if (!prefer_platform_arch && arch.IsValid()) {
     if (!platform_sp->IsCompatibleArchitecture(
             arch, {}, ArchSpec::CompatibleMatch, nullptr)) {
-      platform_sp = platform_list.GetOrCreate(arch, {}, &platform_arch);
+      platform_sp =
+          platform_list.GetOrCreate(arch, {}, &platform_arch, nullptr);
       if (platform_sp)
         platform_list.SetSelectedPlatform(platform_sp);
     }
@@ -228,8 +229,8 @@
     ArchSpec fixed_platform_arch;
     if (!platform_sp->IsCompatibleArchitecture(
             platform_arch, {}, ArchSpec::CompatibleMatch, nullptr)) {
-      platform_sp =
-          platform_list.GetOrCreate(platform_arch, {}, &fixed_platform_arch);
+      platform_sp = platform_list.GetOrCreate(platform_arch, {},
+                                              &fixed_platform_arch, nullptr);
       if (platform_sp)
         platform_list.SetSelectedPlatform(platform_sp);
     }
@@ -260,8 +261,8 @@
   if (arch.IsValid()) {
     if (!platform_sp || !platform_sp->IsCompatibleArchitecture(
                             arch, {}, ArchSpec::CompatibleMatch, nullptr))
-      platform_sp =
-          debugger.GetPlatformList().GetOrCreate(specified_arch, {}, &arch);
+      platform_sp = debugger.GetPlatformList().GetOrCreate(specified_arch, {},
+                                                           &arch, nullptr);
   }
 
   if (!platform_sp)
Index: lldb/source/Target/Target.cpp
===================================================================
--- lldb/source/Target/Target.cpp
+++ lldb/source/Target/Target.cpp
@@ -1502,8 +1502,8 @@
                               other, {}, ArchSpec::CompatibleMatch, nullptr)) {
         ArchSpec platform_arch;
         if (PlatformSP arch_platform_sp =
-                GetDebugger().GetPlatformList().GetOrCreate(other, {},
-                                                            &platform_arch)) {
+                GetDebugger().GetPlatformList().GetOrCreate(
+                    other, {}, &platform_arch, nullptr)) {
           SetPlatform(arch_platform_sp);
           if (platform_arch.IsValid())
             other = platform_arch;
Index: lldb/source/Target/Process.cpp
===================================================================
--- lldb/source/Target/Process.cpp
+++ lldb/source/Target/Process.cpp
@@ -2930,7 +2930,7 @@
                                      ArchSpec::CompatibleMatch, nullptr)) {
       ArchSpec platform_arch;
       platform_sp = GetTarget().GetDebugger().GetPlatformList().GetOrCreate(
-          target_arch, process_host_arch, &platform_arch);
+          target_arch, process_host_arch, &platform_arch, nullptr);
       if (platform_sp) {
         GetTarget().SetPlatform(platform_sp);
         GetTarget().SetArchitecture(platform_arch);
Index: lldb/source/Target/Platform.cpp
===================================================================
--- lldb/source/Target/Platform.cpp
+++ lldb/source/Target/Platform.cpp
@@ -163,40 +163,6 @@
   return FileSpecList();
 }
 
-// PlatformSP
-// Platform::FindPlugin (Process *process, ConstString plugin_name)
-//{
-//    PlatformCreateInstance create_callback = nullptr;
-//    if (plugin_name)
-//    {
-//        create_callback  =
-//        PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name);
-//        if (create_callback)
-//        {
-//            ArchSpec arch;
-//            if (process)
-//            {
-//                arch = process->GetTarget().GetArchitecture();
-//            }
-//            PlatformSP platform_sp(create_callback(process, &arch));
-//            if (platform_sp)
-//                return platform_sp;
-//        }
-//    }
-//    else
-//    {
-//        for (uint32_t idx = 0; (create_callback =
-//        PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != nullptr;
-//        ++idx)
-//        {
-//            PlatformSP platform_sp(create_callback(process, nullptr));
-//            if (platform_sp)
-//                return platform_sp;
-//        }
-//    }
-//    return PlatformSP();
-//}
-
 Status Platform::GetSharedModule(
     const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
     const FileSpecList *module_search_paths_ptr,
@@ -250,14 +216,15 @@
                                              module_spec);
 }
 
-PlatformSP Platform::Create(llvm::StringRef name) {
+PlatformSP Platform::Create(llvm::StringRef name, const Debugger *debugger,
+                            const ScriptedMetadata *metadata) {
   lldb::PlatformSP platform_sp;
   if (name == GetHostPlatformName())
     return GetHostPlatform();
 
   if (PlatformCreateInstance create_callback =
           PluginManager::GetPlatformCreateCallbackForPluginName(name))
-    return create_callback(true, nullptr);
+    return create_callback(true, nullptr, debugger, metadata);
   return nullptr;
 }
 
@@ -1966,19 +1933,20 @@
   return {};
 }
 
-PlatformSP PlatformList::GetOrCreate(llvm::StringRef name) {
+PlatformSP PlatformList::GetOrCreate(llvm::StringRef name,
+                                     const ScriptedMetadata *metadata) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   for (const PlatformSP &platform_sp : m_platforms) {
     if (platform_sp->GetName() == name)
       return platform_sp;
   }
-  return Create(name);
+  return Create(name, metadata);
 }
 
 PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch,
                                      const ArchSpec &process_host_arch,
-                                     ArchSpec *platform_arch_ptr,
-                                     Status &error) {
+                                     ArchSpec *platform_arch_ptr, Status &error,
+                                     const ScriptedMetadata *metadata) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   // First try exact arch matches across all platforms already created
   for (const auto &platform_sp : m_platforms) {
@@ -2001,7 +1969,8 @@
   for (idx = 0;
        (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx));
        ++idx) {
-    PlatformSP platform_sp = create_callback(false, &arch);
+    PlatformSP platform_sp =
+        create_callback(false, &arch, &m_debugger, metadata);
     if (platform_sp &&
         platform_sp->IsCompatibleArchitecture(
             arch, process_host_arch, ArchSpec::ExactMatch, platform_arch_ptr)) {
@@ -2013,7 +1982,8 @@
   for (idx = 0;
        (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx));
        ++idx) {
-    PlatformSP platform_sp = create_callback(false, &arch);
+    PlatformSP platform_sp =
+        create_callback(false, &arch, &m_debugger, metadata);
     if (platform_sp && platform_sp->IsCompatibleArchitecture(
                            arch, process_host_arch, ArchSpec::CompatibleMatch,
                            platform_arch_ptr)) {
@@ -2028,16 +1998,19 @@
 
 PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch,
                                      const ArchSpec &process_host_arch,
-                                     ArchSpec *platform_arch_ptr) {
+                                     ArchSpec *platform_arch_ptr,
+                                     const ScriptedMetadata *metadata) {
   Status error;
   if (arch.IsValid())
-    return GetOrCreate(arch, process_host_arch, platform_arch_ptr, error);
+    return GetOrCreate(arch, process_host_arch, platform_arch_ptr, error,
+                       metadata);
   return nullptr;
 }
 
 PlatformSP PlatformList::GetOrCreate(llvm::ArrayRef<ArchSpec> archs,
                                      const ArchSpec &process_host_arch,
-                                     std::vector<PlatformSP> &candidates) {
+                                     std::vector<PlatformSP> &candidates,
+                                     const ScriptedMetadata *metadata) {
   candidates.clear();
   candidates.reserve(archs.size());
 
@@ -2066,7 +2039,8 @@
 
   // Collect a list of candidate platforms for the architectures.
   for (const ArchSpec &arch : archs) {
-    if (PlatformSP platform = GetOrCreate(arch, process_host_arch, nullptr))
+    if (PlatformSP platform =
+            GetOrCreate(arch, process_host_arch, nullptr, nullptr))
       candidates.push_back(platform);
   }
 
@@ -2087,9 +2061,10 @@
   return nullptr;
 }
 
-PlatformSP PlatformList::Create(llvm::StringRef name) {
+PlatformSP PlatformList::Create(llvm::StringRef name,
+                                const ScriptedMetadata *metadata) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  PlatformSP platform_sp = Platform::Create(name);
+  PlatformSP platform_sp = Platform::Create(name, &m_debugger, metadata);
   m_platforms.push_back(platform_sp);
   return platform_sp;
 }
@@ -2103,7 +2078,7 @@
        (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx));
        ++idx) {
     ArchSpec arch;
-    PlatformSP platform_sp = create_callback(true, &arch);
+    PlatformSP platform_sp = create_callback(true, &arch, &m_debugger, nullptr);
     if (platform_sp) {
       if (platform_sp->LoadPlatformBinaryAndSetup(process, addr, notify))
         return true;
Index: lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
===================================================================
--- lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -25,7 +25,9 @@
 
   static void Terminate();
 
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static llvm::StringRef GetPluginNameStatic() { return "remote-gdb-server"; }
 
Index: lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
===================================================================
--- lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -63,8 +63,10 @@
   Platform::Terminate();
 }
 
-PlatformSP PlatformRemoteGDBServer::CreateInstance(bool force,
-                                                   const ArchSpec *arch) {
+PlatformSP
+PlatformRemoteGDBServer::CreateInstance(bool force, const ArchSpec *arch,
+                                        const Debugger *debugger,
+                                        const ScriptedMetadata *metadata) {
   bool create = force;
   if (!create) {
     create = !arch->TripleVendorWasSpecified() && !arch->TripleOSWasSpecified();
Index: lldb/source/Plugins/Platform/Windows/PlatformWindows.h
===================================================================
--- lldb/source/Plugins/Platform/Windows/PlatformWindows.h
+++ lldb/source/Plugins/Platform/Windows/PlatformWindows.h
@@ -22,8 +22,9 @@
   static void Terminate();
 
   // lldb_private::PluginInterface functions
-  static lldb::PlatformSP CreateInstance(bool force,
-                                         const lldb_private::ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static llvm::StringRef GetPluginNameStatic(bool is_host) {
     return is_host ? Platform::GetHostPlatformName() : "remote-windows";
Index: lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
===================================================================
--- lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -40,8 +40,9 @@
 
 static uint32_t g_initialize_count = 0;
 
-PlatformSP PlatformWindows::CreateInstance(bool force,
-                                           const lldb_private::ArchSpec *arch) {
+PlatformSP PlatformWindows::CreateInstance(bool force, const ArchSpec *arch,
+                                           const Debugger *debugger,
+                                           const ScriptedMetadata *metadata) {
   // The only time we create an instance is when we are creating a remote
   // windows platform
   const bool is_host = false;
@@ -136,10 +137,12 @@
         "can't connect to the host platform '{0}', always connected",
         GetPluginName());
   } else {
-    if (!m_remote_platform_sp)
+    if (!m_remote_platform_sp) {
       m_remote_platform_sp =
           platform_gdb_server::PlatformRemoteGDBServer::CreateInstance(
-              /*force=*/true, nullptr);
+              /*force=*/true, /*arch=*/nullptr, /*debugger=*/nullptr,
+              /*metadata=*/nullptr);
+    }
 
     if (m_remote_platform_sp) {
       if (error.Success()) {
Index: lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
===================================================================
--- lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
+++ lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
@@ -70,7 +70,9 @@
   }
 
 private:
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
   static void DebuggerInitialize(Debugger &debugger);
 
   PlatformQemuUser() : Platform(/*is_host=*/true) {}
Index: lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
===================================================================
--- lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
+++ lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
@@ -103,7 +103,9 @@
   }
 }
 
-PlatformSP PlatformQemuUser::CreateInstance(bool force, const ArchSpec *arch) {
+PlatformSP PlatformQemuUser::CreateInstance(bool force, const ArchSpec *arch,
+                                            const Debugger *debugger,
+                                            const ScriptedMetadata *metadata) {
   if (force)
     return PlatformSP(new PlatformQemuUser());
   return nullptr;
Index: lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
===================================================================
--- lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -309,7 +309,8 @@
     if (!m_remote_platform_sp)
       m_remote_platform_sp =
           platform_gdb_server::PlatformRemoteGDBServer::CreateInstance(
-              /*force=*/true, nullptr);
+              /*force=*/true, /*arch=*/nullptr, /*debugger=*/nullptr,
+              /*metadata=*/nullptr);
 
     if (m_remote_platform_sp && error.Success())
       error = m_remote_platform_sp->ConnectRemote(args);
Index: lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
===================================================================
--- lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
+++ lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
@@ -23,7 +23,9 @@
   static void Terminate();
 
   // lldb_private::PluginInterface functions
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static llvm::StringRef GetPluginNameStatic(bool is_host) {
     return is_host ? Platform::GetHostPlatformName() : "remote-openbsd";
Index: lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
===================================================================
--- lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
+++ lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
@@ -39,8 +39,9 @@
 
 static uint32_t g_initialize_count = 0;
 
-
-PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) {
+PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch,
+                                           const Debugger *debugger,
+                                           const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
            arch ? arch->GetArchitectureName() : "<null>",
Index: lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
===================================================================
--- lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
+++ lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
@@ -24,7 +24,9 @@
   static void Terminate();
 
   // lldb_private::PluginInterface functions
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static llvm::StringRef GetPluginNameStatic(bool is_host) {
     return is_host ? Platform::GetHostPlatformName() : "remote-netbsd";
Index: lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
===================================================================
--- lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -39,8 +39,9 @@
 
 static uint32_t g_initialize_count = 0;
 
-
-PlatformSP PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch) {
+PlatformSP PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch,
+                                          const Debugger *debugger,
+                                          const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
            arch ? arch->GetArchitectureName() : "<null>",
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
@@ -22,7 +22,9 @@
 public:
   PlatformRemoteiOS();
 
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static void Initialize();
 
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -52,7 +52,9 @@
   PlatformDarwin::Terminate();
 }
 
-PlatformSP PlatformRemoteiOS::CreateInstance(bool force, const ArchSpec *arch) {
+PlatformSP PlatformRemoteiOS::CreateInstance(bool force, const ArchSpec *arch,
+                                             const Debugger *debugger,
+                                             const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   if (log) {
     const char *arch_name;
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h
@@ -27,7 +27,9 @@
 public:
   PlatformRemoteMacOSX();
 
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static void Initialize();
 
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.cpp
@@ -57,8 +57,10 @@
   PlatformDarwin::Terminate();
 }
 
-PlatformSP PlatformRemoteMacOSX::CreateInstance(bool force,
-                                                const ArchSpec *arch) {
+PlatformSP
+PlatformRemoteMacOSX::CreateInstance(bool force, const ArchSpec *arch,
+                                     const Debugger *debugger,
+                                     const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   if (log) {
     const char *arch_name;
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
@@ -22,7 +22,9 @@
 public:
   PlatformRemoteAppleWatch();
 
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static void Initialize();
 
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
@@ -54,8 +54,10 @@
   PlatformDarwin::Terminate();
 }
 
-PlatformSP PlatformRemoteAppleWatch::CreateInstance(bool force,
-                                                    const ArchSpec *arch) {
+PlatformSP
+PlatformRemoteAppleWatch::CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   if (log) {
     const char *arch_name;
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
@@ -26,8 +26,9 @@
   PlatformRemoteAppleTV();
 
   // Class Functions
-  static lldb::PlatformSP CreateInstance(bool force,
-                                         const lldb_private::ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static void Initialize();
 
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
@@ -57,8 +57,10 @@
   PlatformDarwin::Terminate();
 }
 
-PlatformSP PlatformRemoteAppleTV::CreateInstance(bool force,
-                                                 const ArchSpec *arch) {
+PlatformSP
+PlatformRemoteAppleTV::CreateInstance(bool force, const ArchSpec *arch,
+                                      const Debugger *debugger,
+                                      const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   if (log) {
     const char *arch_name;
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h
@@ -24,7 +24,9 @@
 public:
   PlatformRemoteAppleBridge();
 
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static void Initialize();
 
Index: lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp
@@ -56,8 +56,10 @@
   PlatformDarwin::Terminate();
 }
 
-PlatformSP PlatformRemoteAppleBridge::CreateInstance(bool force,
-                                                 const ArchSpec *arch) {
+PlatformSP
+PlatformRemoteAppleBridge::CreateInstance(bool force, const ArchSpec *arch,
+                                          const Debugger *debugger,
+                                          const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   if (log) {
     const char *arch_name;
Index: lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
@@ -32,7 +32,9 @@
 public:
   PlatformMacOSX();
 
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static void Initialize();
 
Index: lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -89,7 +89,9 @@
   return "Local Mac OS X user platform plug-in.";
 }
 
-PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) {
+PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch,
+                                          const Debugger *debugger,
+                                          const ScriptedMetadata *metadata) {
   // The only time we create an instance is when we are creating a remote
   // macosx platform which is handled by PlatformRemoteMacOSX.
   return PlatformSP();
Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
@@ -36,7 +36,9 @@
 
 class PlatformDarwinKernel : public PlatformDarwin {
 public:
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static void DebuggerInitialize(Debugger &debugger);
 
Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -72,8 +72,10 @@
   PlatformDarwin::Terminate();
 }
 
-PlatformSP PlatformDarwinKernel::CreateInstance(bool force,
-                                                const ArchSpec *arch) {
+PlatformSP
+PlatformDarwinKernel::CreateInstance(bool force, const ArchSpec *arch,
+                                     const Debugger *debugger,
+                                     const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   if (log) {
     const char *arch_name;
@@ -968,7 +970,7 @@
 
   PlatformSP platform_sp =
       process->GetTarget().GetDebugger().GetPlatformList().Create(
-          PlatformDarwinKernel::GetPluginNameStatic());
+          PlatformDarwinKernel::GetPluginNameStatic(), nullptr);
   if (platform_sp)
     process->GetTarget().SetPlatform(platform_sp);
 
Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -48,7 +48,9 @@
 
   ~PlatformDarwin() override;
 
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static void DebuggerInitialize(lldb_private::Debugger &debugger);
   
Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -105,9 +105,11 @@
   return "Darwin platform plug-in.";
 }
 
-PlatformSP PlatformDarwin::CreateInstance(bool force, const ArchSpec *arch) {
-   // We only create subclasses of the PlatformDarwin plugin.
-   return PlatformSP();
+PlatformSP PlatformDarwin::CreateInstance(bool force, const ArchSpec *arch,
+                                          const Debugger *debugger,
+                                          const ScriptedMetadata *metadata) {
+  // We only create subclasses of the PlatformDarwin plugin.
+  return PlatformSP();
 }
 
 #define LLDB_PROPERTIES_platformdarwin
Index: lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -541,7 +541,9 @@
     PluginManager::UnregisterPlugin(PlatformiOSSimulator::CreateInstance);
   }
 
-  static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
+  static PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                   const Debugger *debugger,
+                                   const ScriptedMetadata *metadata) {
     if (shouldSkipSimulatorPlatform(force, arch))
       return nullptr;
 
@@ -586,7 +588,9 @@
     PluginManager::UnregisterPlugin(PlatformAppleTVSimulator::CreateInstance);
   }
 
-  static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
+  static PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                   const Debugger *debugger,
+                                   const ScriptedMetadata *metadata) {
     if (shouldSkipSimulatorPlatform(force, arch))
       return nullptr;
     return PlatformAppleSimulator::CreateInstance(
@@ -628,7 +632,9 @@
         PlatformAppleWatchSimulator::CreateInstance);
   }
 
-  static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
+  static PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                   const Debugger *debugger,
+                                   const ScriptedMetadata *metadata) {
     if (shouldSkipSimulatorPlatform(force, arch))
       return nullptr;
     return PlatformAppleSimulator::CreateInstance(
Index: lldb/source/Plugins/Platform/Linux/PlatformLinux.h
===================================================================
--- lldb/source/Plugins/Platform/Linux/PlatformLinux.h
+++ lldb/source/Plugins/Platform/Linux/PlatformLinux.h
@@ -24,7 +24,9 @@
   static void Terminate();
 
   // lldb_private::PluginInterface functions
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static llvm::StringRef GetPluginNameStatic(bool is_host) {
     return is_host ? Platform::GetHostPlatformName() : "remote-linux";
Index: lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
===================================================================
--- lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -41,8 +41,9 @@
 
 static uint32_t g_initialize_count = 0;
 
-
-PlatformSP PlatformLinux::CreateInstance(bool force, const ArchSpec *arch) {
+PlatformSP PlatformLinux::CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
            arch ? arch->GetArchitectureName() : "<null>",
Index: lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
===================================================================
--- lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -24,7 +24,9 @@
   static void Terminate();
 
   // lldb_private::PluginInterface functions
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static llvm::StringRef GetPluginNameStatic(bool is_host) {
     return is_host ? Platform::GetHostPlatformName() : "remote-freebsd";
Index: lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
===================================================================
--- lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -44,8 +44,9 @@
 
 static uint32_t g_initialize_count = 0;
 
-
-PlatformSP PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch) {
+PlatformSP PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch,
+                                           const Debugger *debugger,
+                                           const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
            arch ? arch->GetArchitectureName() : "<null>",
Index: lldb/source/Plugins/Platform/Android/PlatformAndroid.h
===================================================================
--- lldb/source/Plugins/Platform/Android/PlatformAndroid.h
+++ lldb/source/Plugins/Platform/Android/PlatformAndroid.h
@@ -28,7 +28,9 @@
   static void Terminate();
 
   // lldb_private::PluginInterface functions
-  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch,
+                                         const Debugger *debugger,
+                                         const ScriptedMetadata *metadata);
 
   static llvm::StringRef GetPluginNameStatic(bool is_host) {
     return is_host ? Platform::GetHostPlatformName() : "remote-android";
Index: lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
===================================================================
--- lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -58,7 +58,9 @@
   PlatformLinux::Terminate();
 }
 
-PlatformSP PlatformAndroid::CreateInstance(bool force, const ArchSpec *arch) {
+PlatformSP PlatformAndroid::CreateInstance(bool force, const ArchSpec *arch,
+                                           const Debugger *debugger,
+                                           const ScriptedMetadata *metadata) {
   Log *log = GetLog(LLDBLog::Platform);
   if (log) {
     const char *arch_name;
Index: lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
===================================================================
--- lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -511,7 +511,7 @@
   process->SetCanRunCode(false);
   PlatformSP platform_sp =
       process->GetTarget().GetDebugger().GetPlatformList().Create(
-          PlatformDarwinKernel::GetPluginNameStatic());
+          PlatformDarwinKernel::GetPluginNameStatic(), nullptr);
   if (platform_sp.get())
     process->GetTarget().SetPlatform(platform_sp);
 }
Index: lldb/source/Interpreter/OptionGroupPlatform.cpp
===================================================================
--- lldb/source/Interpreter/OptionGroupPlatform.cpp
+++ lldb/source/Interpreter/OptionGroupPlatform.cpp
@@ -10,6 +10,7 @@
 
 #include "lldb/Host/OptionParser.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
 #include "lldb/Target/Platform.h"
 
 using namespace lldb;
@@ -22,8 +23,10 @@
 
   PlatformSP platform_sp;
 
+  const ScriptedMetadata metadata(m_class_options);
+
   if (!m_platform_name.empty()) {
-    platform_sp = platforms.Create(m_platform_name);
+    platform_sp = platforms.Create(m_platform_name, &metadata);
     if (!platform_sp) {
       error.SetErrorStringWithFormatv(
           "unable to find a plug-in for the platform named \"{0}\"",
@@ -41,7 +44,8 @@
       }
     }
   } else if (arch.IsValid()) {
-    platform_sp = platforms.GetOrCreate(arch, {}, &platform_arch, error);
+    platform_sp =
+        platforms.GetOrCreate(arch, {}, &platform_arch, error, &metadata);
   }
 
   if (platform_sp) {
Index: lldb/source/Core/Debugger.cpp
===================================================================
--- lldb/source/Core/Debugger.cpp
+++ lldb/source/Core/Debugger.cpp
@@ -746,7 +746,7 @@
       m_error_stream_sp(std::make_shared<StreamFile>(stderr, false)),
       m_input_recorder(nullptr),
       m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
-      m_terminal_state(), m_target_list(*this), m_platform_list(),
+      m_terminal_state(), m_target_list(*this), m_platform_list(*this),
       m_listener_sp(Listener::MakeListener("lldb.Debugger")),
       m_source_manager_up(), m_source_file_cache(),
       m_command_interpreter_up(
Index: lldb/source/Commands/CommandObjectPlatform.h
===================================================================
--- lldb/source/Commands/CommandObjectPlatform.h
+++ lldb/source/Commands/CommandObjectPlatform.h
@@ -10,6 +10,7 @@
 #define LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLATFORM_H
 
 #include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/OptionGroupPlatform.h"
 
 namespace lldb_private {
 
@@ -27,6 +28,23 @@
   operator=(const CommandObjectPlatform &) = delete;
 };
 
+class CommandObjectPlatformSelect : public CommandObjectParsed {
+public:
+  CommandObjectPlatformSelect(CommandInterpreter &interpreter);
+
+  ~CommandObjectPlatformSelect() override = default;
+
+  void HandleCompletion(CompletionRequest &request) override;
+
+  Options *GetOptions() override;
+
+protected:
+  bool DoExecute(Args &args, CommandReturnObject &result) override;
+
+  OptionGroupOptions m_option_group;
+  OptionGroupPlatform m_platform_options;
+};
+
 } // namespace lldb_private
 
 #endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTPLATFORM_H
Index: lldb/source/Commands/CommandObjectPlatform.cpp
===================================================================
--- lldb/source/Commands/CommandObjectPlatform.cpp
+++ lldb/source/Commands/CommandObjectPlatform.cpp
@@ -139,63 +139,58 @@
 };
 
 // "platform select <platform-name>"
-class CommandObjectPlatformSelect : public CommandObjectParsed {
-public:
-  CommandObjectPlatformSelect(CommandInterpreter &interpreter)
-      : CommandObjectParsed(interpreter, "platform select",
-                            "Create a platform if needed and select it as the "
-                            "current platform.",
-                            "platform select <platform-name>", 0),
-        m_platform_options(
-            false) // Don't include the "--platform" option by passing false
-  {
-    m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
-    m_option_group.Finalize();
-    CommandArgumentData platform_arg{eArgTypePlatform, eArgRepeatPlain};
-    m_arguments.push_back({platform_arg});
-  }
+CommandObjectPlatformSelect::CommandObjectPlatformSelect(
+    CommandInterpreter &interpreter)
+    : CommandObjectParsed(interpreter, "platform select",
+                          "Create a platform if needed and select it as the "
+                          "current platform.",
+                          "platform select <platform-name>", 0),
+      m_platform_options(
+          false) // Don't include the "--platform" option by passing false
+{
+  m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
+  m_option_group.Append(&m_platform_options.m_class_options,
+                        LLDB_OPT_SET_1 | LLDB_OPT_SET_2, LLDB_OPT_SET_ALL);
+  m_option_group.Finalize();
+  CommandArgumentData platform_arg{eArgTypePlatform, eArgRepeatPlain};
+  m_arguments.push_back({platform_arg});
+}
 
-  ~CommandObjectPlatformSelect() override = default;
+void CommandObjectPlatformSelect::HandleCompletion(CompletionRequest &request) {
+  CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request,
+                                          nullptr);
+}
 
-  void HandleCompletion(CompletionRequest &request) override {
-    CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request,
-                                            nullptr);
-  }
+Options *CommandObjectPlatformSelect::GetOptions() { return &m_option_group; }
 
-  Options *GetOptions() override { return &m_option_group; }
+bool CommandObjectPlatformSelect::DoExecute(Args &args,
+                                            CommandReturnObject &result) {
+  if (args.GetArgumentCount() == 1) {
+    const char *platform_name = args.GetArgumentAtIndex(0);
+    if (platform_name && platform_name[0]) {
+      const bool select = true;
+      m_platform_options.SetPlatformName(platform_name);
+      Status error;
+      ArchSpec platform_arch;
+      PlatformSP platform_sp(m_platform_options.CreatePlatformWithOptions(
+          m_interpreter, ArchSpec(), select, error, platform_arch));
+      if (platform_sp) {
+        GetDebugger().GetPlatformList().SetSelectedPlatform(platform_sp);
 
-protected:
-  bool DoExecute(Args &args, CommandReturnObject &result) override {
-    if (args.GetArgumentCount() == 1) {
-      const char *platform_name = args.GetArgumentAtIndex(0);
-      if (platform_name && platform_name[0]) {
-        const bool select = true;
-        m_platform_options.SetPlatformName(platform_name);
-        Status error;
-        ArchSpec platform_arch;
-        PlatformSP platform_sp(m_platform_options.CreatePlatformWithOptions(
-            m_interpreter, ArchSpec(), select, error, platform_arch));
-        if (platform_sp) {
-          GetDebugger().GetPlatformList().SetSelectedPlatform(platform_sp);
-
-          platform_sp->GetStatus(result.GetOutputStream());
-          result.SetStatus(eReturnStatusSuccessFinishResult);
-        } else {
-          result.AppendError(error.AsCString());
-        }
+        platform_sp->GetStatus(result.GetOutputStream());
+        result.SetStatus(eReturnStatusSuccessFinishResult);
       } else {
-        result.AppendError("invalid platform name");
+        result.AppendError(error.AsCString());
       }
     } else {
-      result.AppendError(
-          "platform create takes a platform name as an argument\n");
+      result.AppendError("invalid platform name");
     }
-    return result.Succeeded();
+  } else {
+    result.AppendError(
+        "platform create takes a platform name as an argument\n");
   }
-
-  OptionGroupOptions m_option_group;
-  OptionGroupPlatform m_platform_options;
-};
+  return result.Succeeded();
+}
 
 // "platform list"
 class CommandObjectPlatformList : public CommandObjectParsed {
Index: lldb/source/API/SBPlatform.cpp
===================================================================
--- lldb/source/API/SBPlatform.cpp
+++ lldb/source/API/SBPlatform.cpp
@@ -7,11 +7,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/API/SBPlatform.h"
+#include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBEnvironment.h"
 #include "lldb/API/SBError.h"
 #include "lldb/API/SBFileSpec.h"
 #include "lldb/API/SBLaunchInfo.h"
 #include "lldb/API/SBPlatform.h"
+#include "lldb/API/SBStructuredData.h"
 #include "lldb/API/SBUnixSignals.h"
 #include "lldb/Host/File.h"
 #include "lldb/Target/Platform.h"
@@ -19,6 +21,7 @@
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/Args.h"
 #include "lldb/Utility/Instrumentation.h"
+#include "lldb/Utility/ScriptedMetadata.h"
 #include "lldb/Utility/Status.h"
 
 #include "llvm/Support/FileSystem.h"
@@ -292,7 +295,30 @@
 SBPlatform::SBPlatform(const char *platform_name) {
   LLDB_INSTRUMENT_VA(this, platform_name);
 
-  m_opaque_sp = Platform::Create(platform_name);
+  m_opaque_sp = Platform::Create(platform_name, nullptr, nullptr);
+}
+
+SBPlatform::SBPlatform(const char *platform_name, const SBDebugger &debugger,
+                       const char *script_name, const SBStructuredData &dict) {
+  LLDB_INSTRUMENT_VA(this, platform_name, debugger, script_name, 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;
+
+  const ScriptedMetadata metadata(script_name, dict_sp);
+
+  m_opaque_sp =
+      Platform::Create(platform_name, debugger.m_opaque_sp.get(), &metadata);
 }
 
 SBPlatform::SBPlatform(const SBPlatform &rhs) {
Index: lldb/source/API/SBDebugger.cpp
===================================================================
--- lldb/source/API/SBDebugger.cpp
+++ lldb/source/API/SBDebugger.cpp
@@ -1498,7 +1498,8 @@
   if (m_opaque_sp) {
     if (platform_name_cstr && platform_name_cstr[0]) {
       PlatformList &platforms = m_opaque_sp->GetPlatformList();
-      if (PlatformSP platform_sp = platforms.GetOrCreate(platform_name_cstr))
+      if (PlatformSP platform_sp =
+              platforms.GetOrCreate(platform_name_cstr, nullptr))
         platforms.SetSelectedPlatform(platform_sp);
       else
         sb_error.ref().SetErrorString("platform not found");
Index: lldb/include/lldb/lldb-private-interfaces.h
===================================================================
--- lldb/include/lldb/lldb-private-interfaces.h
+++ lldb/include/lldb/lldb-private-interfaces.h
@@ -26,6 +26,7 @@
 } // namespace llvm
 
 namespace lldb_private {
+class ScriptedMetadata;
 typedef lldb::ABISP (*ABICreateInstance)(lldb::ProcessSP process_sp,
                                          const ArchSpec &arch);
 typedef std::unique_ptr<Architecture> (*ArchitectureCreateInstance)(
@@ -77,8 +78,9 @@
 typedef Status (*StructuredDataFilterLaunchInfo)(ProcessLaunchInfo &launch_info,
                                                  Target *target);
 typedef SystemRuntime *(*SystemRuntimeCreateInstance)(Process *process);
-typedef lldb::PlatformSP (*PlatformCreateInstance)(bool force,
-                                                   const ArchSpec *arch);
+typedef lldb::PlatformSP (*PlatformCreateInstance)(
+    bool force, const ArchSpec *arch, const Debugger *debugger,
+    const ScriptedMetadata *metadata);
 typedef lldb::ProcessSP (*ProcessCreateInstance)(
     lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
     const FileSpec *crash_file_path, bool can_connect);
Index: lldb/include/lldb/Target/Platform.h
===================================================================
--- lldb/include/lldb/Target/Platform.h
+++ lldb/include/lldb/Target/Platform.h
@@ -23,6 +23,7 @@
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/ScriptedMetadata.h"
 #include "lldb/Utility/StructuredData.h"
 #include "lldb/Utility/Timeout.h"
 #include "lldb/Utility/UserIDResolver.h"
@@ -98,7 +99,8 @@
 
   static void SetHostPlatform(const lldb::PlatformSP &platform_sp);
 
-  static lldb::PlatformSP Create(llvm::StringRef name);
+  static lldb::PlatformSP Create(llvm::StringRef name, const Debugger *debugger,
+                                 const ScriptedMetadata *metadata);
 
   /// Augments the triple either with information from platform or the host
   /// system (if platform is null).
@@ -973,7 +975,7 @@
 
 class PlatformList {
 public:
-  PlatformList() = default;
+  PlatformList(Debugger &debugger) : m_debugger(debugger) {}
 
   ~PlatformList() = default;
 
@@ -1028,13 +1030,16 @@
     }
   }
 
-  lldb::PlatformSP GetOrCreate(llvm::StringRef name);
+  lldb::PlatformSP GetOrCreate(llvm::StringRef name,
+                               const ScriptedMetadata *metadata);
   lldb::PlatformSP GetOrCreate(const ArchSpec &arch,
                                const ArchSpec &process_host_arch,
-                               ArchSpec *platform_arch_ptr, Status &error);
+                               ArchSpec *platform_arch_ptr, Status &error,
+                               const ScriptedMetadata *metadata);
   lldb::PlatformSP GetOrCreate(const ArchSpec &arch,
                                const ArchSpec &process_host_arch,
-                               ArchSpec *platform_arch_ptr);
+                               ArchSpec *platform_arch_ptr,
+                               const ScriptedMetadata *metadata);
 
   /// Get the platform for the given list of architectures.
   ///
@@ -1050,9 +1055,11 @@
   /// given architecture.
   lldb::PlatformSP GetOrCreate(llvm::ArrayRef<ArchSpec> archs,
                                const ArchSpec &process_host_arch,
-                               std::vector<lldb::PlatformSP> &candidates);
+                               std::vector<lldb::PlatformSP> &candidates,
+                               const ScriptedMetadata *metadata);
 
-  lldb::PlatformSP Create(llvm::StringRef name);
+  lldb::PlatformSP Create(llvm::StringRef name,
+                          const ScriptedMetadata *metadata);
 
   /// Detect a binary in memory that will determine which Platform and
   /// DynamicLoader should be used in this target/process, and update
@@ -1089,6 +1096,7 @@
 private:
   PlatformList(const PlatformList &) = delete;
   const PlatformList &operator=(const PlatformList &) = delete;
+  Debugger &m_debugger;
 };
 
 class OptionGroupPlatformRSync : public lldb_private::OptionGroup {
Index: lldb/include/lldb/Interpreter/OptionGroupPlatform.h
===================================================================
--- lldb/include/lldb/Interpreter/OptionGroupPlatform.h
+++ lldb/include/lldb/Interpreter/OptionGroupPlatform.h
@@ -9,19 +9,22 @@
 #ifndef LLDB_INTERPRETER_OPTIONGROUPPLATFORM_H
 #define LLDB_INTERPRETER_OPTIONGROUPPLATFORM_H
 
+#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
 #include "lldb/Interpreter/Options.h"
 #include "lldb/Utility/ConstString.h"
 #include "llvm/Support/VersionTuple.h"
 
 namespace lldb_private {
 
+class CommandObjectPlatformSelect;
 // PlatformOptionGroup
 //
 // Make platform options available to any commands that need the settings.
 class OptionGroupPlatform : public OptionGroup {
 public:
   OptionGroupPlatform(bool include_platform_option)
-      : m_include_platform_option(include_platform_option) {}
+      : m_include_platform_option(include_platform_option),
+        m_class_options("scripted platform", true, 'C', 'K', 'V', 0) {}
 
   ~OptionGroupPlatform() override = default;
 
@@ -60,11 +63,14 @@
   bool PlatformMatches(const lldb::PlatformSP &platform_sp) const;
 
 protected:
+  friend class CommandObjectPlatformSelect;
+
   std::string m_platform_name;
   ConstString m_sdk_sysroot;
   ConstString m_sdk_build;
   llvm::VersionTuple m_os_version;
   bool m_include_platform_option;
+  OptionGroupPythonClassWithDict m_class_options;
 };
 
 } // namespace lldb_private
Index: lldb/include/lldb/API/SBStructuredData.h
===================================================================
--- lldb/include/lldb/API/SBStructuredData.h
+++ lldb/include/lldb/API/SBStructuredData.h
@@ -93,6 +93,7 @@
   friend class SBLaunchInfo;
   friend class SBDebugger;
   friend class SBTarget;
+  friend class SBPlatform;
   friend class SBProcess;
   friend class SBThread;
   friend class SBThreadPlan;
Index: lldb/include/lldb/API/SBPlatform.h
===================================================================
--- lldb/include/lldb/API/SBPlatform.h
+++ lldb/include/lldb/API/SBPlatform.h
@@ -96,6 +96,9 @@
 
   SBPlatform(const char *platform_name);
 
+  SBPlatform(const char *platform_name, const SBDebugger &debugger,
+             const char *script_name, const SBStructuredData &dict);
+
   SBPlatform(const SBPlatform &rhs);
 
   SBPlatform &operator=(const SBPlatform &rhs);
Index: lldb/include/lldb/API/SBDebugger.h
===================================================================
--- lldb/include/lldb/API/SBDebugger.h
+++ lldb/include/lldb/API/SBDebugger.h
@@ -420,6 +420,7 @@
                             const SBFileSpec &trace_description_file);
 
 private:
+  friend class SBPlatform;
   friend class SBCommandInterpreter;
   friend class SBInputReader;
   friend class SBListener;
Index: lldb/bindings/interface/SBPlatform.i
===================================================================
--- lldb/bindings/interface/SBPlatform.i
+++ lldb/bindings/interface/SBPlatform.i
@@ -126,6 +126,9 @@
 
     SBPlatform (const char *);
 
+    SBPlatform (const char *, const SBDebugger&,
+                const char *, const SBStructuredData&);
+
     ~SBPlatform();
 
     static SBPlatform GetHostPlatform();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to