diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -322,7 +322,13 @@ /// \b true if \a arch was filled in and is valid, \b false /// otherwise. virtual bool GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) = 0; + ArchSpec &arch); + + /// Get the platform's supported architectures in the order in which they + /// should be searched. + /// NB: This implementation is mutually recursive with + /// GetSupportedArchitectureAtIndex. Subclasses should implement one of them. + virtual std::vector GetSupportedArchitectures(); virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site); @@ -876,6 +882,12 @@ } protected: + /// Create a list of ArchSpecs with the given OS and a architectures. The + /// vendor field is left as an "unspecified unknown". + static std::vector + CreateArchList(llvm::ArrayRef archs, + llvm::Triple::OSType os); + /// Private implementation of connecting to a process. If the stream is set /// we connect synchronously. lldb::ProcessSP DoConnectProcess(llvm::StringRef connect_url, diff --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h --- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h +++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h @@ -42,7 +42,7 @@ void GetStatus(Stream &strm) override; - bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override; + std::vector GetSupportedArchitectures() override; bool CanDebugProcess() override; @@ -52,6 +52,8 @@ lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset) override; + + std::vector m_supported_architectures; }; } // namespace platform_freebsd diff --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp --- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -111,72 +111,27 @@ /// Default Constructor PlatformFreeBSD::PlatformFreeBSD(bool is_host) : PlatformPOSIX(is_host) // This is the local host platform -{} - -bool PlatformFreeBSD::GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) { - if (IsHost()) { +{ + if (is_host) { ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); - if (hostArch.GetTriple().isOSFreeBSD()) { - if (idx == 0) { - arch = hostArch; - return arch.IsValid(); - } else if (idx == 1) { - // If the default host architecture is 64-bit, look for a 32-bit - // variant - if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) { - arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); - return arch.IsValid(); - } - } + m_supported_architectures.push_back(hostArch); + if (hostArch.GetTriple().isArch64Bit()) { + m_supported_architectures.push_back( + HostInfo::GetArchitecture(HostInfo::eArchKind32)); } } else { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch); - - llvm::Triple triple; - // Set the OS to FreeBSD - triple.setOS(llvm::Triple::FreeBSD); - // Set the architecture - switch (idx) { - case 0: - triple.setArchName("x86_64"); - break; - case 1: - triple.setArchName("i386"); - break; - case 2: - triple.setArchName("aarch64"); - break; - case 3: - triple.setArchName("arm"); - break; - case 4: - triple.setArchName("mips64"); - break; - case 5: - triple.setArchName("mips"); - break; - case 6: - triple.setArchName("ppc64"); - break; - case 7: - triple.setArchName("ppc"); - break; - default: - return false; - } - // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the - // vendor by calling triple.SetVendorName("unknown") so that it is a - // "unspecified unknown". This means when someone calls - // triple.GetVendorName() it will return an empty string which indicates - // that the vendor can be set when two architectures are merged - - // Now set the triple into "arch" and return true - arch.SetTriple(triple); - return true; + m_supported_architectures = CreateArchList( + {llvm::Triple::x86_64, llvm::Triple::x86, llvm::Triple::aarch64, + llvm::Triple::arm, llvm::Triple::mips64, llvm::Triple::ppc64, + llvm::Triple::ppc}, + llvm::Triple::FreeBSD); } - return false; +} + +std::vector PlatformFreeBSD::GetSupportedArchitectures() { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetSupportedArchitectures(); + return m_supported_architectures; } void PlatformFreeBSD::GetStatus(Stream &strm) { diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h @@ -42,7 +42,7 @@ void GetStatus(Stream &strm) override; - bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override; + std::vector GetSupportedArchitectures() override; uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override; @@ -57,6 +57,8 @@ lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset) override; + + std::vector m_supported_architectures; }; } // namespace platform_linux diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -109,78 +109,28 @@ /// Default Constructor PlatformLinux::PlatformLinux(bool is_host) : PlatformPOSIX(is_host) // This is the local host platform -{} - -bool PlatformLinux::GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) { - if (IsHost()) { +{ + if (is_host) { ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); - if (hostArch.GetTriple().isOSLinux()) { - if (idx == 0) { - arch = hostArch; - return arch.IsValid(); - } else if (idx == 1) { - // If the default host architecture is 64-bit, look for a 32-bit - // variant - if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) { - arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); - return arch.IsValid(); - } - } + m_supported_architectures.push_back(hostArch); + if (hostArch.GetTriple().isArch64Bit()) { + m_supported_architectures.push_back( + HostInfo::GetArchitecture(HostInfo::eArchKind32)); } } else { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch); - - llvm::Triple triple; - // Set the OS to linux - triple.setOS(llvm::Triple::Linux); - // Set the architecture - switch (idx) { - case 0: - triple.setArchName("x86_64"); - break; - case 1: - triple.setArchName("i386"); - break; - case 2: - triple.setArchName("arm"); - break; - case 3: - triple.setArchName("aarch64"); - break; - case 4: - triple.setArchName("mips64"); - break; - case 5: - triple.setArchName("hexagon"); - break; - case 6: - triple.setArchName("mips"); - break; - case 7: - triple.setArchName("mips64el"); - break; - case 8: - triple.setArchName("mipsel"); - break; - case 9: - triple.setArchName("s390x"); - break; - default: - return false; - } - // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the - // vendor by calling triple.SetVendorName("unknown") so that it is a - // "unspecified unknown". This means when someone calls - // triple.GetVendorName() it will return an empty string which indicates - // that the vendor can be set when two architectures are merged - - // Now set the triple into "arch" and return true - arch.SetTriple(triple); - return true; + m_supported_architectures = CreateArchList( + {llvm::Triple::x86_64, llvm::Triple::x86, llvm::Triple::arm, + llvm::Triple::aarch64, llvm::Triple::mips64, llvm::Triple::mips64, + llvm::Triple::hexagon, llvm::Triple::mips, llvm::Triple::mips64el, + llvm::Triple::mipsel, llvm::Triple::systemz}, + llvm::Triple::Linux); } - return false; +} + +std::vector PlatformLinux::GetSupportedArchitectures() { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetSupportedArchitectures(); + return m_supported_architectures; } void PlatformLinux::GetStatus(Stream &strm) { diff --git a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h --- a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h +++ b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h @@ -42,7 +42,7 @@ void GetStatus(Stream &strm) override; - bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override; + std::vector GetSupportedArchitectures() override; uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override; @@ -54,6 +54,8 @@ lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset) override; + + std::vector m_supported_architectures; }; } // namespace platform_netbsd diff --git a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp --- a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp +++ b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp @@ -100,54 +100,24 @@ /// Default Constructor PlatformNetBSD::PlatformNetBSD(bool is_host) : PlatformPOSIX(is_host) // This is the local host platform -{} - -bool PlatformNetBSD::GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) { - if (IsHost()) { +{ + if (is_host) { ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); - if (hostArch.GetTriple().isOSNetBSD()) { - if (idx == 0) { - arch = hostArch; - return arch.IsValid(); - } else if (idx == 1) { - // If the default host architecture is 64-bit, look for a 32-bit - // variant - if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) { - arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); - return arch.IsValid(); - } - } + m_supported_architectures.push_back(hostArch); + if (hostArch.GetTriple().isArch64Bit()) { + m_supported_architectures.push_back( + HostInfo::GetArchitecture(HostInfo::eArchKind32)); } } else { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch); - - llvm::Triple triple; - // Set the OS to NetBSD - triple.setOS(llvm::Triple::NetBSD); - // Set the architecture - switch (idx) { - case 0: - triple.setArchName("x86_64"); - break; - case 1: - triple.setArchName("i386"); - break; - default: - return false; - } - // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the - // vendor by calling triple.SetVendorName("unknown") so that it is a - // "unspecified unknown". This means when someone calls - // triple.GetVendorName() it will return an empty string which indicates - // that the vendor can be set when two architectures are merged - - // Now set the triple into "arch" and return true - arch.SetTriple(triple); - return true; + m_supported_architectures = CreateArchList( + {llvm::Triple::x86_64, llvm::Triple::x86}, llvm::Triple::NetBSD); } - return false; +} + +std::vector PlatformNetBSD::GetSupportedArchitectures() { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetSupportedArchitectures(); + return m_supported_architectures; } void PlatformNetBSD::GetStatus(Stream &strm) { diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -1144,6 +1144,35 @@ return platform_sp; } +std::vector +Platform::CreateArchList(llvm::ArrayRef archs, + llvm::Triple::OSType os) { + std::vector list; + for(auto arch : archs) { + llvm::Triple triple; + triple.setArch(arch); + triple.setOS(os); + list.push_back(ArchSpec(triple)); + } + return list; +} + +bool Platform::GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) { + const auto &archs = GetSupportedArchitectures(); + if (idx >= archs.size()) + return false; + arch = archs[idx]; + return true; +} + +std::vector Platform::GetSupportedArchitectures() { + std::vector result; + ArchSpec arch; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(idx, arch); ++idx) + result.push_back(arch); + return result; +} + /// Lets a platform answer if it is compatible with a given /// architecture and the target triple contained within. bool Platform::IsCompatibleArchitecture(const ArchSpec &arch,