labath created this revision. labath added reviewers: JDevlieghere, clayborg, jingham. Herald added subscribers: mgorny, emaste. Herald added a project: All. labath requested review of this revision. Herald added a project: LLDB.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D120810 Files: lldb/include/lldb/Target/Platform.h 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/debugger/elf.yaml lldb/test/API/python_api/debugger/macho.yaml lldb/test/API/python_api/sbplatform/TestSBPlatform.py
Index: lldb/test/API/python_api/sbplatform/TestSBPlatform.py =================================================================== --- lldb/test/API/python_api/sbplatform/TestSBPlatform.py +++ lldb/test/API/python_api/sbplatform/TestSBPlatform.py @@ -25,6 +25,29 @@ 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()) Index: lldb/test/API/python_api/debugger/macho.yaml =================================================================== --- /dev/null +++ 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 +... Index: lldb/test/API/python_api/debugger/elf.yaml =================================================================== --- /dev/null +++ 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 + Index: lldb/test/API/python_api/debugger/TestDebuggerAPI.py =================================================================== --- lldb/test/API/python_api/debugger/TestDebuggerAPI.py +++ lldb/test/API/python_api/debugger/TestDebuggerAPI.py @@ -92,3 +92,55 @@ # 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") Index: lldb/source/Target/TargetList.cpp =================================================================== --- lldb/source/Target/TargetList.cpp +++ lldb/source/Target/TargetList.cpp @@ -79,8 +79,9 @@ 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 @@ -200,9 +201,8 @@ // Finally find a platform that matches the architecture in the // executable file. - PlatformSP fallback_platform_sp( - Platform::GetPlatformForArchitecture( - module_spec.GetArchitecture(), nullptr)); + PlatformSP fallback_platform_sp = platform_list.GetOrCreate( + module_spec.GetArchitecture(), nullptr); if (fallback_platform_sp) { platforms.push_back(fallback_platform_sp); } @@ -258,19 +258,19 @@ // 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); + platform_sp = + platform_list.GetOrCreate(platform_arch, &fixed_platform_arch); if (platform_sp) - debugger.GetPlatformList().SetSelectedPlatform(platform_sp); + platform_list.SetSelectedPlatform(platform_sp); } } @@ -299,7 +299,8 @@ if (arch.IsValid()) { if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) - platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); + platform_sp = + debugger.GetPlatformList().GetOrCreate(specified_arch, &arch); } if (!platform_sp) Index: lldb/source/Target/Target.cpp =================================================================== --- lldb/source/Target/Target.cpp +++ lldb/source/Target/Target.cpp @@ -1472,9 +1472,9 @@ 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; Index: lldb/source/Target/Process.cpp =================================================================== --- lldb/source/Target/Process.cpp +++ lldb/source/Target/Process.cpp @@ -2890,8 +2890,8 @@ if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(target_arch, false, nullptr)) { ArchSpec platform_arch; - platform_sp = - platform_sp->GetPlatformForArchitecture(target_arch, &platform_arch); + platform_sp = GetTarget().GetDebugger().GetPlatformList().GetOrCreate( + target_arch, &platform_arch); 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 @@ -49,8 +49,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() { @@ -135,26 +133,9 @@ /// 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; -} +void Platform::Initialize() {} -static std::recursive_mutex &GetPlatformListMutex() { - static std::recursive_mutex g_mutex; - return g_mutex; -} - -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::Terminate() {} PlatformProperties &Platform::GetGlobalPlatformProperties() { static PlatformProperties g_settings; @@ -165,11 +146,6 @@ // 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, @@ -272,108 +248,15 @@ 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 (name == GetHostPlatformName()) + return GetHostPlatform(); - if (platform_sp) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformListMutex()); - GetPlatformList().push_back(platform_sp); - } - - return platform_sp; -} - -PlatformSP Platform::Create(const ArchSpec &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, 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, 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, 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, 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) { @@ -1200,16 +1083,6 @@ return process_sp; } -lldb::PlatformSP -Platform::GetPlatformForArchitecture(const ArchSpec &arch, - ArchSpec *platform_arch_ptr) { - lldb::PlatformSP platform_sp; - Status error; - if (arch.IsValid()) - platform_sp = Platform::Create(arch, platform_arch_ptr, error); - return platform_sp; -} - std::vector<ArchSpec> Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs, llvm::Triple::OSType os) { @@ -2005,3 +1878,72 @@ 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, + 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, 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, 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, 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, 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, + ArchSpec *platform_arch_ptr) { + Status error; + if (arch.IsValid()) + return GetOrCreate(arch, platform_arch_ptr, error); + 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; +} Index: lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt =================================================================== --- lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt +++ lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt @@ -7,4 +7,5 @@ lldbHost lldbTarget lldbPluginProcessUtility + lldbPluginProcessGDBRemote ) Index: lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp =================================================================== --- lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp +++ 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 @@ } 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()) { Index: lldb/source/Plugins/Platform/Windows/CMakeLists.txt =================================================================== --- lldb/source/Plugins/Platform/Windows/CMakeLists.txt +++ lldb/source/Plugins/Platform/Windows/CMakeLists.txt @@ -6,6 +6,7 @@ lldbCore lldbHost lldbTarget + lldbPluginPlatformGDB LINK_COMPONENTS Support Index: lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ 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 @@ } 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); Index: lldb/source/Plugins/Platform/POSIX/CMakeLists.txt =================================================================== --- lldb/source/Plugins/Platform/POSIX/CMakeLists.txt +++ lldb/source/Plugins/Platform/POSIX/CMakeLists.txt @@ -7,5 +7,6 @@ lldbHost lldbInterpreter lldbTarget + lldbPluginPlatformGDB lldbPluginTypeSystemClang ) 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,8 +511,9 @@ 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); } Index: lldb/source/Interpreter/OptionGroupPlatform.cpp =================================================================== --- lldb/source/Interpreter/OptionGroupPlatform.cpp +++ lldb/source/Interpreter/OptionGroupPlatform.cpp @@ -18,10 +18,17 @@ 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,14 @@ } } } else if (arch.IsValid()) { - platform_sp = Platform::Create(arch, &platform_arch, error); + platform_sp = platforms.GetOrCreate(arch, &platform_arch, error); + if (platform_sp) + platforms.Append(platform_sp, make_selected); } 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); Index: lldb/source/API/SBPlatform.cpp =================================================================== --- lldb/source/API/SBPlatform.cpp +++ lldb/source/API/SBPlatform.cpp @@ -293,9 +293,7 @@ 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) { Index: lldb/source/API/SBDebugger.cpp =================================================================== --- lldb/source/API/SBDebugger.cpp +++ lldb/source/API/SBDebugger.cpp @@ -1428,21 +1428,11 @@ 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"); } Index: lldb/include/lldb/Target/Platform.h =================================================================== --- lldb/include/lldb/Target/Platform.h +++ lldb/include/lldb/Target/Platform.h @@ -94,20 +94,11 @@ /// attaching to processes unless another platform is specified. static lldb::PlatformSP GetHostPlatform(); - static lldb::PlatformSP - GetPlatformForArchitecture(const ArchSpec &arch, ArchSpec *platform_arch_ptr); - 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, - 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). @@ -1015,6 +1006,14 @@ } } + lldb::PlatformSP GetOrCreate(llvm::StringRef name); + lldb::PlatformSP GetOrCreate(const ArchSpec &arch, ArchSpec *platform_arch_ptr, + Status &error); + lldb::PlatformSP GetOrCreate(const ArchSpec &arch, + ArchSpec *platform_arch_ptr); + + lldb::PlatformSP Create(llvm::StringRef name); + protected: typedef std::vector<lldb::PlatformSP> collection; mutable std::recursive_mutex m_mutex;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits