[Lldb-commits] [lldb] af92100 - [lldb] Remove the global platform list

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 13 05:41:35 PDT 2022


Author: Pavel Labath
Date: 2022-04-13T14:41:13+02:00
New Revision: af921006d3792fa28d1070f015dcfd145e082ed2

URL: https://github.com/llvm/llvm-project/commit/af921006d3792fa28d1070f015dcfd145e082ed2
DIFF: https://github.com/llvm/llvm-project/commit/af921006d3792fa28d1070f015dcfd145e082ed2.diff

LOG: [lldb] Remove the global platform list

This patch moves the platform creation and selection logic into the
per-debugger platform lists. I've tried to keep functional changes to a
minimum -- the main (only) observable difference in this change is that
APIs, which select a platform by name (e.g.,
Debugger::SetCurrentPlatform) will not automatically pick up a platform
associated with another debugger (or no debugger at all).

I've also added several tests for this functionality -- one of the
pleasant consequences of the debugger isolation is that it is now
possible to test the platform selection and creation logic.

This is a product of the discussion at
<https://discourse.llvm.org/t/multiple-platforms-with-the-same-name/59594>.

Differential Revision: https://reviews.llvm.org/D120810

Added: 
    lldb/test/API/python_api/debugger/elf.yaml
    lldb/test/API/python_api/debugger/macho.yaml

Modified: 
    lldb/include/lldb/Target/Platform.h
    lldb/packages/Python/lldbsuite/test/dotest.py
    lldb/source/API/SBDebugger.cpp
    lldb/source/API/SBPlatform.cpp
    lldb/source/Interpreter/OptionGroupPlatform.cpp
    lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
    lldb/source/Plugins/Platform/POSIX/CMakeLists.txt
    lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
    lldb/source/Plugins/Platform/Windows/CMakeLists.txt
    lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
    lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt
    lldb/source/Target/Platform.cpp
    lldb/source/Target/Process.cpp
    lldb/source/Target/Target.cpp
    lldb/source/Target/TargetList.cpp
    lldb/test/API/python_api/debugger/TestDebuggerAPI.py
    lldb/test/API/python_api/sbplatform/TestSBPlatform.py
    lldb/unittests/Platform/PlatformTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 3b02f44a7fe21..8b8ca6268071f 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -94,79 +94,11 @@ class Platform : public PluginInterface {
   /// attaching to processes unless another platform is specified.
   static lldb::PlatformSP GetHostPlatform();
 
-  /// Get the platform for the given architecture. See Platform::Create for how
-  /// a platform is chosen for a given architecture.
-  ///
-  /// \param[in] arch
-  ///     The architecture for which we are getting a platform.
-  ///
-  /// \param[in] process_host_arch
-  ///     The process host architecture if it's known. An invalid ArchSpec
-  ///     represents that the process host architecture is unknown.
-  ///
-  /// \param[out] platform_arch_ptr
-  ///     The architecture which was used to pick the returned platform. This
-  ///     can be 
diff erent from the input architecture if we're looking for a
-  ///     compatible match instead of an exact match.
-  ///
-  /// \return
-  ///     Return the platform that matches the input architecture or the
-  ///     default (invalid) platform if none could be found.
-  static lldb::PlatformSP
-  GetPlatformForArchitecture(const ArchSpec &arch,
-                             const ArchSpec &process_host_arch = {},
-                             ArchSpec *platform_arch_ptr = nullptr);
-
-  /// Get the platform for the given list of architectures.
-  ///
-  /// The algorithm works a follows:
-  ///
-  /// 1. Returns the selected platform if it matches any of the architectures.
-  /// 2. Returns the host platform if it matches any of the architectures.
-  /// 3. Returns the platform that matches all the architectures.
-  ///
-  /// If none of the above apply, this function returns a default platform. The
-  /// candidates output argument 
diff erentiates between either no platforms
-  /// supporting the given architecture or multiple platforms supporting the
-  /// given architecture.
-  ///
-  /// \param[in] arch
-  ///     The architecture for which we are getting a platform.
-  ///
-  /// \param[in] process_host_arch
-  ///     The process host architecture if it's known. An invalid ArchSpec
-  ///     represents that the process host architecture is unknown.
-  ///
-  /// \param[in] selected_platform_sp
-  ///     The currently selected platform.
-  ///
-  /// \param[out] candidates
-  ///     A list of candidate platforms in case multiple platforms could
-  ///     support the given list of architectures. If no platforms match the
-  ///     given architecture the list will be empty.
-  ///
-  /// \return
-  ///     Return the platform that matches the input architectures or the
-  ///     default (invalid) platform if no platforms support the given
-  ///     architectures or multiple platforms support the given architecture.
-  static lldb::PlatformSP
-  GetPlatformForArchitectures(std::vector<ArchSpec> archs,
-                              const ArchSpec &process_host_arch,
-                              lldb::PlatformSP selected_platform_sp,
-                              std::vector<lldb::PlatformSP> &candidates);
-
   static const char *GetHostPlatformName();
 
   static void SetHostPlatform(const lldb::PlatformSP &platform_sp);
 
-  // Find an existing platform plug-in by name
-  static lldb::PlatformSP Find(ConstString name);
-
-  static lldb::PlatformSP Create(ConstString name, Status &error);
-
-  static lldb::PlatformSP Create(const ArchSpec &arch,
-                                 const ArchSpec &process_host_arch,
-                                 ArchSpec *platform_arch_ptr, Status &error);
+  static lldb::PlatformSP Create(llvm::StringRef name);
 
   /// Augments the triple either with information from platform or the host
   /// system (if platform is null).
@@ -917,9 +849,6 @@ class Platform : public PluginInterface {
   virtual CompilerType GetSiginfoType(const llvm::Triple &triple);
 
 protected:
-  /// For unit testing purposes only.
-  static void Clear();
-
   /// Create a list of ArchSpecs with the given OS and a architectures. The
   /// vendor field is left as an "unspecified unknown".
   static std::vector<ArchSpec>
@@ -1069,6 +998,32 @@ class PlatformList {
     }
   }
 
+  lldb::PlatformSP GetOrCreate(llvm::StringRef name);
+  lldb::PlatformSP GetOrCreate(const ArchSpec &arch,
+                               const ArchSpec &process_host_arch,
+                               ArchSpec *platform_arch_ptr, Status &error);
+  lldb::PlatformSP GetOrCreate(const ArchSpec &arch,
+                               const ArchSpec &process_host_arch,
+                               ArchSpec *platform_arch_ptr);
+
+  /// Get the platform for the given list of architectures.
+  ///
+  /// The algorithm works a follows:
+  ///
+  /// 1. Returns the selected platform if it matches any of the architectures.
+  /// 2. Returns the host platform if it matches any of the architectures.
+  /// 3. Returns the platform that matches all the architectures.
+  ///
+  /// If none of the above apply, this function returns a default platform. The
+  /// candidates output argument 
diff erentiates between either no platforms
+  /// supporting the given architecture or multiple platforms supporting the
+  /// given architecture.
+  lldb::PlatformSP GetOrCreate(llvm::ArrayRef<ArchSpec> archs,
+                               const ArchSpec &process_host_arch,
+                               std::vector<lldb::PlatformSP> &candidates);
+
+  lldb::PlatformSP Create(llvm::StringRef name);
+
 protected:
   typedef std::vector<lldb::PlatformSP> collection;
   mutable std::recursive_mutex m_mutex;

diff  --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index 489e6ce7bd7a1..a9ca741cf3a72 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -902,6 +902,7 @@ def run_suite():
               (configuration.lldb_platform_name))
         lldb.remote_platform = lldb.SBPlatform(
             configuration.lldb_platform_name)
+        lldb.selected_platform = lldb.remote_platform
         if not lldb.remote_platform.IsValid():
             print(
                 "error: unable to create the LLDB platform named '%s'." %
@@ -918,7 +919,6 @@ def run_suite():
             err = lldb.remote_platform.ConnectRemote(platform_connect_options)
             if err.Success():
                 print("Connected.")
-                lldb.selected_platform = lldb.remote_platform
             else:
                 print("error: failed to connect to remote platform using URL '%s': %s" % (
                     configuration.lldb_platform_url, err))

diff  --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index c82ff0f1e878d..ea340e3a44792 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -1460,21 +1460,11 @@ SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) {
   SBError sb_error;
   if (m_opaque_sp) {
     if (platform_name_cstr && platform_name_cstr[0]) {
-      ConstString platform_name(platform_name_cstr);
-      PlatformSP platform_sp(Platform::Find(platform_name));
-
-      if (platform_sp) {
-        // Already have a platform with this name, just select it
-        m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp);
-      } else {
-        // We don't have a platform by this name yet, create one
-        platform_sp = Platform::Create(platform_name, sb_error.ref());
-        if (platform_sp) {
-          // We created the platform, now append and select it
-          bool make_selected = true;
-          m_opaque_sp->GetPlatformList().Append(platform_sp, make_selected);
-        }
-      }
+      PlatformList &platforms = m_opaque_sp->GetPlatformList();
+      if (PlatformSP platform_sp = platforms.GetOrCreate(platform_name_cstr))
+        platforms.SetSelectedPlatform(platform_sp);
+      else
+        sb_error.ref().SetErrorString("platform not found");
     } else {
       sb_error.ref().SetErrorString("invalid platform name");
     }

diff  --git a/lldb/source/API/SBPlatform.cpp b/lldb/source/API/SBPlatform.cpp
index 15a6966798454..ac767f740a305 100644
--- a/lldb/source/API/SBPlatform.cpp
+++ b/lldb/source/API/SBPlatform.cpp
@@ -292,9 +292,7 @@ SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); }
 SBPlatform::SBPlatform(const char *platform_name) {
   LLDB_INSTRUMENT_VA(this, platform_name);
 
-  Status error;
-  if (platform_name && platform_name[0])
-    m_opaque_sp = Platform::Create(ConstString(platform_name), error);
+  m_opaque_sp = Platform::Create(platform_name);
 }
 
 SBPlatform::SBPlatform(const SBPlatform &rhs) {

diff  --git a/lldb/source/Interpreter/OptionGroupPlatform.cpp b/lldb/source/Interpreter/OptionGroupPlatform.cpp
index 9550edc2613e6..acdf3f293496f 100644
--- a/lldb/source/Interpreter/OptionGroupPlatform.cpp
+++ b/lldb/source/Interpreter/OptionGroupPlatform.cpp
@@ -18,10 +18,17 @@ using namespace lldb_private;
 PlatformSP OptionGroupPlatform::CreatePlatformWithOptions(
     CommandInterpreter &interpreter, const ArchSpec &arch, bool make_selected,
     Status &error, ArchSpec &platform_arch) const {
+  PlatformList &platforms = interpreter.GetDebugger().GetPlatformList();
+
   PlatformSP platform_sp;
 
   if (!m_platform_name.empty()) {
-    platform_sp = Platform::Create(ConstString(m_platform_name.c_str()), error);
+    platform_sp = platforms.Create(m_platform_name);
+    if (!platform_sp) {
+      error.SetErrorStringWithFormatv(
+          "unable to find a plug-in for the platform named \"{0}\"",
+          m_platform_name);
+    }
     if (platform_sp) {
       if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(
                                          arch, {}, false, &platform_arch)) {
@@ -33,12 +40,12 @@ PlatformSP OptionGroupPlatform::CreatePlatformWithOptions(
       }
     }
   } else if (arch.IsValid()) {
-    platform_sp = Platform::Create(arch, {}, &platform_arch, error);
+    platform_sp = platforms.GetOrCreate(arch, {}, &platform_arch, error);
   }
 
   if (platform_sp) {
-    interpreter.GetDebugger().GetPlatformList().Append(platform_sp,
-                                                       make_selected);
+    if (make_selected)
+      platforms.SetSelectedPlatform(platform_sp);
     if (!m_os_version.empty())
       platform_sp->SetOSVersion(m_os_version);
 

diff  --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 036450bf17d3b..1b699f293b37f 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -511,8 +511,9 @@ DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
       m_kext_summary_header(), m_known_kexts(), m_mutex(),
       m_break_id(LLDB_INVALID_BREAK_ID) {
   Status error;
-  PlatformSP platform_sp(Platform::Create(
-      ConstString(PlatformDarwinKernel::GetPluginNameStatic()), error));
+  PlatformSP platform_sp =
+      process->GetTarget().GetDebugger().GetPlatformList().Create(
+          PlatformDarwinKernel::GetPluginNameStatic());
   if (platform_sp.get())
     process->GetTarget().SetPlatform(platform_sp);
 }

diff  --git a/lldb/source/Plugins/Platform/POSIX/CMakeLists.txt b/lldb/source/Plugins/Platform/POSIX/CMakeLists.txt
index 6f52deabc855d..78eb7bc60e0ea 100644
--- a/lldb/source/Plugins/Platform/POSIX/CMakeLists.txt
+++ b/lldb/source/Plugins/Platform/POSIX/CMakeLists.txt
@@ -7,5 +7,6 @@ add_lldb_library(lldbPluginPlatformPOSIX
     lldbHost
     lldbInterpreter
     lldbTarget
+    lldbPluginPlatformGDB
     lldbPluginTypeSystemClang
   )

diff  --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index a274065fded23..9a2f0972f9993 100644
--- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -8,6 +8,7 @@
 
 #include "PlatformPOSIX.h"
 
+#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Module.h"
@@ -307,7 +308,8 @@ Status PlatformPOSIX::ConnectRemote(Args &args) {
   } else {
     if (!m_remote_platform_sp)
       m_remote_platform_sp =
-          Platform::Create(ConstString("remote-gdb-server"), error);
+          platform_gdb_server::PlatformRemoteGDBServer::CreateInstance(
+              /*force=*/true, nullptr);
 
     if (m_remote_platform_sp && error.Success())
       error = m_remote_platform_sp->ConnectRemote(args);

diff  --git a/lldb/source/Plugins/Platform/Windows/CMakeLists.txt b/lldb/source/Plugins/Platform/Windows/CMakeLists.txt
index 28c174dc4d95e..2820ae77e7491 100644
--- a/lldb/source/Plugins/Platform/Windows/CMakeLists.txt
+++ b/lldb/source/Plugins/Platform/Windows/CMakeLists.txt
@@ -6,6 +6,7 @@ add_lldb_library(lldbPluginPlatformWindows PLUGIN
     lldbCore
     lldbHost
     lldbTarget
+    lldbPluginPlatformGDB
 
    LINK_COMPONENTS
     Support

diff  --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
index 708268ff900bc..b0501af7df30b 100644
--- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -14,6 +14,8 @@
 #include <winsock2.h>
 #endif
 
+#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Breakpoint/BreakpointSite.h"
 #include "lldb/Core/Debugger.h"
@@ -28,8 +30,6 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Utility/Status.h"
 
-#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
-
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/ConvertUTF.h"
 
@@ -140,7 +140,8 @@ Status PlatformWindows::ConnectRemote(Args &args) {
   } else {
     if (!m_remote_platform_sp)
       m_remote_platform_sp =
-          Platform::Create(ConstString("remote-gdb-server"), error);
+          platform_gdb_server::PlatformRemoteGDBServer::CreateInstance(
+              /*force=*/true, nullptr);
 
     if (m_remote_platform_sp) {
       if (error.Success()) {

diff  --git a/lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt b/lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt
index 2e3302590b443..2fbe817acbdd2 100644
--- a/lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt
+++ b/lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt
@@ -7,4 +7,5 @@ add_lldb_library(lldbPluginPlatformGDB PLUGIN
     lldbHost
     lldbTarget
     lldbPluginProcessUtility
+    lldbPluginProcessGDBRemote
   )

diff  --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 2dff0dbfae9ee..1976aa636a046 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -51,8 +51,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-static uint32_t g_initialize_count = 0;
-
 // Use a singleton function for g_local_platform_sp to avoid init constructors
 // since LLDB is often part of a shared library
 static PlatformSP &GetHostPlatformSP() {
@@ -137,28 +135,9 @@ void PlatformProperties::SetDefaultModuleCacheDirectory(
 /// or attaching to processes unless another platform is specified.
 PlatformSP Platform::GetHostPlatform() { return GetHostPlatformSP(); }
 
-static std::vector<PlatformSP> &GetPlatformList() {
-  static std::vector<PlatformSP> g_platform_list;
-  return g_platform_list;
-}
-
-static std::recursive_mutex &GetPlatformListMutex() {
-  static std::recursive_mutex g_mutex;
-  return g_mutex;
-}
+void Platform::Initialize() {}
 
-void Platform::Initialize() { g_initialize_count++; }
-
-void Platform::Terminate() {
-  if (g_initialize_count > 0) {
-    if (--g_initialize_count == 0) {
-      std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
-      GetPlatformList().clear();
-    }
-  }
-}
-
-void Platform::Clear() { GetPlatformList().clear(); }
+void Platform::Terminate() {}
 
 PlatformProperties &Platform::GetGlobalPlatformProperties() {
   static PlatformProperties g_settings;
@@ -169,11 +148,6 @@ void Platform::SetHostPlatform(const lldb::PlatformSP &platform_sp) {
   // The native platform should use its static void Platform::Initialize()
   // function to register itself as the native platform.
   GetHostPlatformSP() = platform_sp;
-
-  if (platform_sp) {
-    std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
-    GetPlatformList().push_back(platform_sp);
-  }
 }
 
 Status Platform::GetFileWithUUID(const FileSpec &platform_file,
@@ -276,109 +250,15 @@ bool Platform::GetModuleSpec(const FileSpec &module_file_spec,
                                              module_spec);
 }
 
-PlatformSP Platform::Find(ConstString name) {
-  if (name) {
-    static ConstString g_host_platform_name("host");
-    if (name == g_host_platform_name)
-      return GetHostPlatform();
-
-    std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
-    for (const auto &platform_sp : GetPlatformList()) {
-      if (platform_sp->GetName() == name.GetStringRef())
-        return platform_sp;
-    }
-  }
-  return PlatformSP();
-}
-
-PlatformSP Platform::Create(ConstString name, Status &error) {
-  PlatformCreateInstance create_callback = nullptr;
+PlatformSP Platform::Create(llvm::StringRef name) {
   lldb::PlatformSP platform_sp;
-  if (name) {
-    static ConstString g_host_platform_name("host");
-    if (name == g_host_platform_name)
-      return GetHostPlatform();
-
-    create_callback = PluginManager::GetPlatformCreateCallbackForPluginName(
-        name.GetStringRef());
-    if (create_callback)
-      platform_sp = create_callback(true, nullptr);
-    else
-      error.SetErrorStringWithFormat(
-          "unable to find a plug-in for the platform named \"%s\"",
-          name.GetCString());
-  } else
-    error.SetErrorString("invalid platform name");
-
-  if (platform_sp) {
-    std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
-    GetPlatformList().push_back(platform_sp);
-  }
+  if (name == GetHostPlatformName())
+    return GetHostPlatform();
 
-  return platform_sp;
-}
-
-PlatformSP Platform::Create(const ArchSpec &arch,
-                            const ArchSpec &process_host_arch,
-                            ArchSpec *platform_arch_ptr, Status &error) {
-  lldb::PlatformSP platform_sp;
-  if (arch.IsValid()) {
-    // Scope for locker
-    {
-      // First try exact arch matches across all platforms already created
-      std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
-      for (const auto &platform_sp : GetPlatformList()) {
-        if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch, true,
-                                                  platform_arch_ptr))
-          return platform_sp;
-      }
-
-      // Next try compatible arch matches across all platforms already created
-      for (const auto &platform_sp : GetPlatformList()) {
-        if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch,
-                                                  false, platform_arch_ptr))
-          return platform_sp;
-      }
-    }
-
-    PlatformCreateInstance create_callback;
-    // First try exact arch matches across all platform plug-ins
-    uint32_t idx;
-    for (idx = 0; (create_callback =
-                       PluginManager::GetPlatformCreateCallbackAtIndex(idx));
-         ++idx) {
-      if (create_callback) {
-        platform_sp = create_callback(false, &arch);
-        if (platform_sp &&
-            platform_sp->IsCompatibleArchitecture(arch, process_host_arch, true,
-                                                  platform_arch_ptr)) {
-          std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
-          GetPlatformList().push_back(platform_sp);
-          return platform_sp;
-        }
-      }
-    }
-    // Next try compatible arch matches across all platform plug-ins
-    for (idx = 0; (create_callback =
-                       PluginManager::GetPlatformCreateCallbackAtIndex(idx));
-         ++idx) {
-      if (create_callback) {
-        platform_sp = create_callback(false, &arch);
-        if (platform_sp &&
-            platform_sp->IsCompatibleArchitecture(arch, process_host_arch,
-                                                  false, platform_arch_ptr)) {
-          std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex());
-          GetPlatformList().push_back(platform_sp);
-          return platform_sp;
-        }
-      }
-    }
-  } else
-    error.SetErrorString("invalid platform name");
-  if (platform_arch_ptr)
-    platform_arch_ptr->Clear();
-  platform_sp.reset();
-  return platform_sp;
+  if (PlatformCreateInstance create_callback =
+          PluginManager::GetPlatformCreateCallbackForPluginName(name))
+    return create_callback(true, nullptr);
+  return nullptr;
 }
 
 ArchSpec Platform::GetAugmentedArchSpec(Platform *platform, llvm::StringRef triple) {
@@ -1258,73 +1138,6 @@ lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info,
   return process_sp;
 }
 
-lldb::PlatformSP
-Platform::GetPlatformForArchitecture(const ArchSpec &arch,
-                                     const ArchSpec &process_host_arch,
-                                     ArchSpec *platform_arch_ptr) {
-  lldb::PlatformSP platform_sp;
-  Status error;
-  if (arch.IsValid())
-    platform_sp =
-        Platform::Create(arch, process_host_arch, platform_arch_ptr, error);
-  return platform_sp;
-}
-
-lldb::PlatformSP Platform::GetPlatformForArchitectures(
-    std::vector<ArchSpec> archs, const ArchSpec &process_host_arch,
-    lldb::PlatformSP selected_platform_sp,
-    std::vector<lldb::PlatformSP> &candidates) {
-  candidates.clear();
-  candidates.reserve(archs.size());
-
-  if (archs.empty())
-    return nullptr;
-
-  PlatformSP host_platform_sp = Platform::GetHostPlatform();
-
-  // Prefer the selected platform if it matches at least one architecture.
-  if (selected_platform_sp) {
-    for (const ArchSpec &arch : archs) {
-      if (selected_platform_sp->IsCompatibleArchitecture(
-              arch, process_host_arch, false, nullptr))
-        return selected_platform_sp;
-    }
-  }
-
-  // Prefer the host platform if it matches at least one architecture.
-  if (host_platform_sp) {
-    for (const ArchSpec &arch : archs) {
-      if (host_platform_sp->IsCompatibleArchitecture(arch, process_host_arch,
-                                                     false, nullptr))
-        return host_platform_sp;
-    }
-  }
-
-  // Collect a list of candidate platforms for the architectures.
-  for (const ArchSpec &arch : archs) {
-    if (PlatformSP platform =
-            Platform::GetPlatformForArchitecture(arch, process_host_arch))
-      candidates.push_back(platform);
-  }
-
-  // The selected or host platform didn't match any of the architectures. If
-  // the same platform supports all architectures then that's the obvious next
-  // best thing.
-  if (candidates.size() == archs.size()) {
-    if (std::all_of(candidates.begin(), candidates.end(),
-                    [&](const PlatformSP &p) -> bool {
-                      return p->GetName() == candidates.front()->GetName();
-                    })) {
-      return candidates.front();
-    }
-  }
-
-  // At this point we either have no platforms that match the given
-  // architectures or multiple platforms with no good way to disambiguate
-  // between them.
-  return nullptr;
-}
-
 std::vector<ArchSpec>
 Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs,
                          llvm::Triple::OSType os) {
@@ -2131,3 +1944,129 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
 CompilerType Platform::GetSiginfoType(const llvm::Triple& triple) {
   return CompilerType();
 }
+
+PlatformSP PlatformList::GetOrCreate(llvm::StringRef name) {
+  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);
+}
+
+PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch,
+                                     const ArchSpec &process_host_arch,
+                                     ArchSpec *platform_arch_ptr,
+                                     Status &error) {
+  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) {
+    if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch, true,
+                                              platform_arch_ptr))
+      return platform_sp;
+  }
+
+  // Next try compatible arch matches across all platforms already created
+  for (const auto &platform_sp : m_platforms) {
+    if (platform_sp->IsCompatibleArchitecture(arch, process_host_arch, false,
+                                              platform_arch_ptr))
+      return platform_sp;
+  }
+
+  PlatformCreateInstance create_callback;
+  // First try exact arch matches across all platform plug-ins
+  uint32_t idx;
+  for (idx = 0;
+       (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx));
+       ++idx) {
+    PlatformSP platform_sp = create_callback(false, &arch);
+    if (platform_sp && platform_sp->IsCompatibleArchitecture(
+                           arch, process_host_arch, true, platform_arch_ptr)) {
+      m_platforms.push_back(platform_sp);
+      return platform_sp;
+    }
+  }
+  // Next try compatible arch matches across all platform plug-ins
+  for (idx = 0;
+       (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx));
+       ++idx) {
+    PlatformSP platform_sp = create_callback(false, &arch);
+    if (platform_sp && platform_sp->IsCompatibleArchitecture(
+                           arch, process_host_arch, false, platform_arch_ptr)) {
+      m_platforms.push_back(platform_sp);
+      return platform_sp;
+    }
+  }
+  if (platform_arch_ptr)
+    platform_arch_ptr->Clear();
+  return nullptr;
+}
+
+PlatformSP PlatformList::GetOrCreate(const ArchSpec &arch,
+                                     const ArchSpec &process_host_arch,
+                                     ArchSpec *platform_arch_ptr) {
+  Status error;
+  if (arch.IsValid())
+    return GetOrCreate(arch, process_host_arch, platform_arch_ptr, error);
+  return nullptr;
+}
+
+PlatformSP PlatformList::GetOrCreate(llvm::ArrayRef<ArchSpec> archs,
+                                     const ArchSpec &process_host_arch,
+                                     std::vector<PlatformSP> &candidates) {
+  candidates.clear();
+  candidates.reserve(archs.size());
+
+  if (archs.empty())
+    return nullptr;
+
+  PlatformSP host_platform_sp = Platform::GetHostPlatform();
+
+  // Prefer the selected platform if it matches at least one architecture.
+  if (m_selected_platform_sp) {
+    for (const ArchSpec &arch : archs) {
+      if (m_selected_platform_sp->IsCompatibleArchitecture(
+              arch, process_host_arch, false, nullptr))
+        return m_selected_platform_sp;
+    }
+  }
+
+  // Prefer the host platform if it matches at least one architecture.
+  if (host_platform_sp) {
+    for (const ArchSpec &arch : archs) {
+      if (host_platform_sp->IsCompatibleArchitecture(arch, process_host_arch,
+                                                     false, nullptr))
+        return host_platform_sp;
+    }
+  }
+
+  // Collect a list of candidate platforms for the architectures.
+  for (const ArchSpec &arch : archs) {
+    if (PlatformSP platform = GetOrCreate(arch, process_host_arch, nullptr))
+      candidates.push_back(platform);
+  }
+
+  // The selected or host platform didn't match any of the architectures. If
+  // the same platform supports all architectures then that's the obvious next
+  // best thing.
+  if (candidates.size() == archs.size()) {
+    if (std::all_of(candidates.begin(), candidates.end(),
+                    [&](const PlatformSP &p) -> bool {
+                      return p->GetName() == candidates.front()->GetName();
+                    })) {
+      return candidates.front();
+    }
+  }
+
+  // At this point we either have no platforms that match the given
+  // architectures or multiple platforms with no good way to disambiguate
+  // between them.
+  return nullptr;
+}
+
+PlatformSP PlatformList::Create(llvm::StringRef name) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  PlatformSP platform_sp = Platform::Create(name);
+  m_platforms.push_back(platform_sp);
+  return platform_sp;
+}

diff  --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 54a19833c8a65..0d19c2b11f42c 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -2892,7 +2892,7 @@ void Process::CompleteAttach() {
         !platform_sp->IsCompatibleArchitecture(target_arch, process_host_arch,
                                                false, nullptr)) {
       ArchSpec platform_arch;
-      platform_sp = platform_sp->GetPlatformForArchitecture(
+      platform_sp = GetTarget().GetDebugger().GetPlatformList().GetOrCreate(
           target_arch, process_host_arch, &platform_arch);
       if (platform_sp) {
         GetTarget().SetPlatform(platform_sp);

diff  --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 71991085145ab..8f0a8be50ff6d 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -1485,9 +1485,9 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
       if (!platform_sp ||
           !platform_sp->IsCompatibleArchitecture(other, {}, false, nullptr)) {
         ArchSpec platform_arch;
-        auto arch_platform_sp =
-            Platform::GetPlatformForArchitecture(other, {}, &platform_arch);
-        if (arch_platform_sp) {
+        if (PlatformSP arch_platform_sp =
+                GetDebugger().GetPlatformList().GetOrCreate(other, {},
+                                                            &platform_arch)) {
           SetPlatform(arch_platform_sp);
           if (platform_arch.IsValid())
             other = platform_arch;

diff  --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index 8d980d000253a..72b50811b8745 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -79,8 +79,9 @@ Status TargetList::CreateTargetInternal(
     const OptionGroupPlatform *platform_options, TargetSP &target_sp) {
   Status error;
 
+  PlatformList &platform_list = debugger.GetPlatformList();
   // Let's start by looking at the selected platform.
-  PlatformSP platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
+  PlatformSP platform_sp = platform_list.GetSelectedPlatform();
 
   // This variable corresponds to the architecture specified by the triple
   // string. If that string was empty the currently selected platform will
@@ -176,8 +177,7 @@ Status TargetList::CreateTargetInternal(
         for (const ModuleSpec &spec : module_specs.ModuleSpecs())
           archs.push_back(spec.GetArchitecture());
         if (PlatformSP platform_for_archs_sp =
-                Platform::GetPlatformForArchitectures(archs, {}, platform_sp,
-                                                      candidates)) {
+                platform_list.GetOrCreate(archs, {}, candidates)) {
           platform_sp = platform_for_archs_sp;
         } else if (candidates.empty()) {
           error.SetErrorString("no matching platforms found for this file");
@@ -209,21 +209,19 @@ Status TargetList::CreateTargetInternal(
   // compatible with that architecture.
   if (!prefer_platform_arch && arch.IsValid()) {
     if (!platform_sp->IsCompatibleArchitecture(arch, {}, false, nullptr)) {
-      platform_sp =
-          Platform::GetPlatformForArchitecture(arch, {}, &platform_arch);
+      platform_sp = platform_list.GetOrCreate(arch, {}, &platform_arch);
       if (platform_sp)
-        debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
+        platform_list.SetSelectedPlatform(platform_sp);
     }
   } else if (platform_arch.IsValid()) {
     // If "arch" isn't valid, yet "platform_arch" is, it means we have an
     // executable file with a single architecture which should be used.
     ArchSpec fixed_platform_arch;
-    if (!platform_sp->IsCompatibleArchitecture(platform_arch, {}, false,
-                                               nullptr)) {
-      platform_sp = Platform::GetPlatformForArchitecture(platform_arch, {},
-                                                         &fixed_platform_arch);
+    if (!platform_sp->IsCompatibleArchitecture(platform_arch, {}, false, nullptr)) {
+      platform_sp =
+          platform_list.GetOrCreate(platform_arch, {}, &fixed_platform_arch);
       if (platform_sp)
-        debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
+        platform_list.SetSelectedPlatform(platform_sp);
     }
   }
 
@@ -253,7 +251,7 @@ Status TargetList::CreateTargetInternal(Debugger &debugger,
     if (!platform_sp ||
         !platform_sp->IsCompatibleArchitecture(arch, {}, false, nullptr))
       platform_sp =
-          Platform::GetPlatformForArchitecture(specified_arch, {}, &arch);
+          debugger.GetPlatformList().GetOrCreate(specified_arch, {}, &arch);
   }
 
   if (!platform_sp)

diff  --git a/lldb/test/API/python_api/debugger/TestDebuggerAPI.py b/lldb/test/API/python_api/debugger/TestDebuggerAPI.py
index 0a19945af1097..f0ba1d1e20aae 100644
--- a/lldb/test/API/python_api/debugger/TestDebuggerAPI.py
+++ b/lldb/test/API/python_api/debugger/TestDebuggerAPI.py
@@ -92,3 +92,55 @@ def get_cache_line_size():
 
         # Test the local property again, is it set to new_cache_line_size?
         self.assertEqual(get_cache_line_size(), new_cache_line_size)
+
+    def test_CreateTarget_platform(self):
+        exe = self.getBuildArtifact("a.out")
+        self.yaml2obj("elf.yaml", exe)
+        error = lldb.SBError()
+        target1 = self.dbg.CreateTarget(exe, None, "remote-linux",
+                False, error)
+        self.assertSuccess(error)
+        platform1 = target1.GetPlatform()
+        platform1.SetWorkingDirectory("/foo/bar")
+
+        # Reuse a platform if it matches the currently selected one...
+        target2 = self.dbg.CreateTarget(exe, None, "remote-linux",
+                False, error)
+        self.assertSuccess(error)
+        platform2 = target2.GetPlatform()
+        self.assertEqual(platform2.GetWorkingDirectory(), "/foo/bar")
+
+        # ... but create a new one if it doesn't.
+        self.dbg.SetSelectedPlatform(lldb.SBPlatform("remote-windows"))
+        target3 = self.dbg.CreateTarget(exe, None, "remote-linux",
+                False, error)
+        self.assertSuccess(error)
+        platform3 = target3.GetPlatform()
+        self.assertIsNone(platform3.GetWorkingDirectory())
+
+    def test_CreateTarget_arch(self):
+        exe = self.getBuildArtifact("a.out")
+        if lldbplatformutil.getHostPlatform() == 'linux':
+            self.yaml2obj("macho.yaml", exe)
+            arch = "x86_64-apple-macosx"
+        else:
+            self.yaml2obj("elf.yaml", exe)
+            arch = "x86_64-pc-linux"
+
+        fbsd = lldb.SBPlatform("remote-freebsd")
+        self.dbg.SetSelectedPlatform(fbsd)
+
+        error = lldb.SBError()
+        target1 = self.dbg.CreateTarget(exe, arch, None, False, error)
+        self.assertSuccess(error)
+        platform1 = target1.GetPlatform()
+        self.assertEqual(platform1.GetName(), "remote-macosx")
+        platform1.SetWorkingDirectory("/foo/bar")
+
+        # Reuse a platform even if it is not currently selected.
+        self.dbg.SetSelectedPlatform(fbsd)
+        target2 = self.dbg.CreateTarget(exe, arch, None, False, error)
+        self.assertSuccess(error)
+        platform2 = target2.GetPlatform()
+        self.assertEqual(platform2.GetName(), "remote-macosx")
+        self.assertEqual(platform2.GetWorkingDirectory(), "/foo/bar")

diff  --git a/lldb/test/API/python_api/debugger/elf.yaml b/lldb/test/API/python_api/debugger/elf.yaml
new file mode 100644
index 0000000000000..d62ebaac847c6
--- /dev/null
+++ b/lldb/test/API/python_api/debugger/elf.yaml
@@ -0,0 +1,35 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x1000
+    AddressAlign:    0x4
+    Content:         "c3c3c3c3"
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x2000
+    AddressAlign:    0x4
+    Content:         "3232"
+ProgramHeaders:
+  - Type: PT_LOAD
+    Flags: [ PF_X, PF_R ]
+    VAddr: 0x1000
+    PAddr: 0x1000
+    Align: 0x4
+    FirstSec: .text
+    LastSec:  .text
+  - Type: PT_LOAD
+    Flags: [ PF_R, PF_W ]
+    VAddr: 0x2000
+    PAddr: 0x1004
+    Align: 0x4
+    FirstSec: .data
+    LastSec:  .data
+

diff  --git a/lldb/test/API/python_api/debugger/macho.yaml b/lldb/test/API/python_api/debugger/macho.yaml
new file mode 100644
index 0000000000000..5fdef2901385a
--- /dev/null
+++ b/lldb/test/API/python_api/debugger/macho.yaml
@@ -0,0 +1,42 @@
+--- !mach-o
+FileHeader:      
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           4
+  sizeofcmds:      1160
+  flags:           0x00002000
+  reserved:        0x00000000
+LoadCommands:    
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         1032
+    segname:         ''
+    vmaddr:          0
+    vmsize:          744
+    fileoff:         1192
+    filesize:        744
+    maxprot:         7
+    initprot:        7
+    nsects:          12
+    flags:           0
+    Sections:        
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0000000000000000
+        size:            22
+        offset:          0x000004A8
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         24
+    platform:        1
+    minos:           658944
+    sdk:             658944
+    ntools:          0
+...

diff  --git a/lldb/test/API/python_api/sbplatform/TestSBPlatform.py b/lldb/test/API/python_api/sbplatform/TestSBPlatform.py
index 002d9a68490f6..dbb3f4ca5db1c 100644
--- a/lldb/test/API/python_api/sbplatform/TestSBPlatform.py
+++ b/lldb/test/API/python_api/sbplatform/TestSBPlatform.py
@@ -25,6 +25,29 @@ def test_SetSDKRoot(self):
         plat = lldb.SBPlatform("remote-linux") # arbitrary choice
         self.assertTrue(plat)
         plat.SetSDKRoot(self.getBuildDir())
-        self.dbg.SetCurrentPlatform("remote-linux")
+        self.dbg.SetSelectedPlatform(plat)
         self.expect("platform status",
                 substrs=["Sysroot:", self.getBuildDir()])
+
+    def test_SetCurrentPlatform_floating(self):
+        # floating platforms cannot be referenced by name until they are
+        # associated with a debugger
+        floating_platform = lldb.SBPlatform("remote-netbsd")
+        floating_platform.SetWorkingDirectory(self.getBuildDir())
+        self.assertSuccess(self.dbg.SetCurrentPlatform("remote-netbsd"))
+        dbg_platform = self.dbg.GetSelectedPlatform()
+        self.assertEqual(dbg_platform.GetName(), "remote-netbsd")
+        self.assertIsNone(dbg_platform.GetWorkingDirectory())
+
+    def test_SetCurrentPlatform_associated(self):
+        # associated platforms are found by name-based lookup
+        floating_platform = lldb.SBPlatform("remote-netbsd")
+        floating_platform.SetWorkingDirectory(self.getBuildDir())
+        orig_platform = self.dbg.GetSelectedPlatform()
+
+        self.dbg.SetSelectedPlatform(floating_platform)
+        self.dbg.SetSelectedPlatform(orig_platform)
+        self.assertSuccess(self.dbg.SetCurrentPlatform("remote-netbsd"))
+        dbg_platform = self.dbg.GetSelectedPlatform()
+        self.assertEqual(dbg_platform.GetName(), "remote-netbsd")
+        self.assertEqual(dbg_platform.GetWorkingDirectory(), self.getBuildDir())

diff  --git a/lldb/unittests/Platform/PlatformTest.cpp b/lldb/unittests/Platform/PlatformTest.cpp
index e5e94e04ee072..8ab223ea2cd57 100644
--- a/lldb/unittests/Platform/PlatformTest.cpp
+++ b/lldb/unittests/Platform/PlatformTest.cpp
@@ -21,7 +21,6 @@ using namespace lldb_private;
 class TestPlatform : public PlatformPOSIX {
 public:
   TestPlatform() : PlatformPOSIX(false) {}
-  using Platform::Clear;
 };
 
 class PlatformArm : public TestPlatform {
@@ -75,67 +74,66 @@ class PlatformThumb : public TestPlatform {
 
 class PlatformTest : public ::testing::Test {
   SubsystemRAII<FileSystem, HostInfo> subsystems;
-  void SetUp() override { TestPlatform::Clear(); }
+
+protected:
+  PlatformList list;
+
+  void SetHostPlatform(const PlatformSP &platform_sp) {
+    Platform::SetHostPlatform(platform_sp);
+    ASSERT_EQ(Platform::GetHostPlatform(), platform_sp);
+    list.Append(platform_sp, /*set_selected=*/true);
+  }
 };
 
 TEST_F(PlatformTest, GetPlatformForArchitecturesHost) {
-  const PlatformSP host_platform_sp = std::make_shared<PlatformArm>();
-  Platform::SetHostPlatform(host_platform_sp);
-  ASSERT_EQ(Platform::GetHostPlatform(), host_platform_sp);
+  SetHostPlatform(std::make_shared<PlatformArm>());
 
   const std::vector<ArchSpec> archs = {ArchSpec("arm64-apple-ps4"),
                                        ArchSpec("arm64e-apple-ps4")};
   std::vector<PlatformSP> candidates;
 
   // The host platform matches all architectures.
-  PlatformSP platform_sp =
-      Platform::GetPlatformForArchitectures(archs, {}, {}, candidates);
+  PlatformSP platform_sp = list.GetOrCreate(archs, {}, candidates);
   ASSERT_TRUE(platform_sp);
-  EXPECT_EQ(platform_sp, host_platform_sp);
+  EXPECT_EQ(platform_sp, Platform::GetHostPlatform());
 }
 
 TEST_F(PlatformTest, GetPlatformForArchitecturesSelected) {
-  const PlatformSP host_platform_sp = std::make_shared<PlatformIntel>();
-  Platform::SetHostPlatform(host_platform_sp);
-  ASSERT_EQ(Platform::GetHostPlatform(), host_platform_sp);
+  SetHostPlatform(std::make_shared<PlatformIntel>());
 
   const std::vector<ArchSpec> archs = {ArchSpec("arm64-apple-ps4"),
                                        ArchSpec("arm64e-apple-ps4")};
   std::vector<PlatformSP> candidates;
 
-  // The host platform matches no architectures. No selected platform.
-  PlatformSP platform_sp =
-      Platform::GetPlatformForArchitectures(archs, {}, {}, candidates);
+  // The host platform matches no architectures.
+  PlatformSP platform_sp = list.GetOrCreate(archs, {}, candidates);
   ASSERT_FALSE(platform_sp);
 
   // The selected platform matches all architectures.
   const PlatformSP selected_platform_sp = std::make_shared<PlatformArm>();
-  platform_sp = Platform::GetPlatformForArchitectures(
-      archs, {}, selected_platform_sp, candidates);
+  list.Append(selected_platform_sp, /*set_selected=*/true);
+  platform_sp = list.GetOrCreate(archs, {}, candidates);
   ASSERT_TRUE(platform_sp);
   EXPECT_EQ(platform_sp, selected_platform_sp);
 }
 
 TEST_F(PlatformTest, GetPlatformForArchitecturesSelectedOverHost) {
-  const PlatformSP host_platform_sp = std::make_shared<PlatformIntel>();
-  Platform::SetHostPlatform(host_platform_sp);
-  ASSERT_EQ(Platform::GetHostPlatform(), host_platform_sp);
+  SetHostPlatform(std::make_shared<PlatformIntel>());
 
   const std::vector<ArchSpec> archs = {ArchSpec("arm64-apple-ps4"),
                                        ArchSpec("x86_64-apple-ps4")};
   std::vector<PlatformSP> candidates;
 
-  // The host platform matches one architecture. No selected platform.
-  PlatformSP platform_sp =
-      Platform::GetPlatformForArchitectures(archs, {}, {}, candidates);
+  // The host platform matches one architecture.
+  PlatformSP platform_sp = list.GetOrCreate(archs, {}, candidates);
   ASSERT_TRUE(platform_sp);
-  EXPECT_EQ(platform_sp, host_platform_sp);
+  EXPECT_EQ(platform_sp, Platform::GetHostPlatform());
 
   // The selected and host platform each match one architecture.
   // The selected platform is preferred.
   const PlatformSP selected_platform_sp = std::make_shared<PlatformArm>();
-  platform_sp = Platform::GetPlatformForArchitectures(
-      archs, {}, selected_platform_sp, candidates);
+  list.Append(selected_platform_sp, /*set_selected=*/true);
+  platform_sp = list.GetOrCreate(archs, {}, candidates);
   ASSERT_TRUE(platform_sp);
   EXPECT_EQ(platform_sp, selected_platform_sp);
 }
@@ -143,18 +141,17 @@ TEST_F(PlatformTest, GetPlatformForArchitecturesSelectedOverHost) {
 TEST_F(PlatformTest, GetPlatformForArchitecturesCandidates) {
   PlatformThumb::Initialize();
 
-  const PlatformSP host_platform_sp = std::make_shared<PlatformIntel>();
-  Platform::SetHostPlatform(host_platform_sp);
-  ASSERT_EQ(Platform::GetHostPlatform(), host_platform_sp);
+  SetHostPlatform(std::make_shared<PlatformIntel>());
+
   const PlatformSP selected_platform_sp = std::make_shared<PlatformArm>();
+  list.Append(selected_platform_sp, /*set_selected=*/true);
 
   const std::vector<ArchSpec> archs = {ArchSpec("thumbv7-apple-ps4"),
                                        ArchSpec("thumbv7f-apple-ps4")};
   std::vector<PlatformSP> candidates;
 
-  // The host platform matches one architecture. No selected platform.
-  PlatformSP platform_sp = Platform::GetPlatformForArchitectures(
-      archs, {}, selected_platform_sp, candidates);
+  // The host platform matches one architecture.
+  PlatformSP platform_sp = list.GetOrCreate(archs, {}, candidates);
   ASSERT_TRUE(platform_sp);
   EXPECT_EQ(platform_sp->GetName(), "thumb");
 


        


More information about the lldb-commits mailing list