forked from OSchip/llvm-project
[lldb] Simplify specifying of platform supported architectures
The GetSupportedArchitectureAtIndex pattern forces the use of complicated patterns in both the implementations of the function and in the various callers. This patch creates a new method (GetSupportedArchitectures), which returns a list (vector) of architectures. The GetSupportedArchitectureAtIndex is kept in order to enable incremental rollout. Base Platform class contains implementations of both of these methods, using the other method as the source of truth. Platforms without infinite stacks should implement at least one of them. This patch also ports Linux, FreeBSD and NetBSD platforms to the new API. A new helper function (CreateArchList) is added to simplify the common task of creating a list of ArchSpecs with the same OS but different architectures. Differential Revision: https://reviews.llvm.org/D113608
This commit is contained in:
parent
33c0f93f6c
commit
669e57ebd1
|
@ -322,7 +322,13 @@ public:
|
|||
/// \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<ArchSpec> GetSupportedArchitectures();
|
||||
|
||||
virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target,
|
||||
BreakpointSite *bp_site);
|
||||
|
@ -876,6 +882,12 @@ public:
|
|||
}
|
||||
|
||||
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<ArchSpec>
|
||||
CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> 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,
|
||||
|
|
|
@ -111,72 +111,27 @@ void PlatformFreeBSD::Terminate() {
|
|||
/// 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<ArchSpec> PlatformFreeBSD::GetSupportedArchitectures() {
|
||||
if (m_remote_platform_sp)
|
||||
return m_remote_platform_sp->GetSupportedArchitectures();
|
||||
return m_supported_architectures;
|
||||
}
|
||||
|
||||
void PlatformFreeBSD::GetStatus(Stream &strm) {
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
|
||||
void GetStatus(Stream &strm) override;
|
||||
|
||||
bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
|
||||
std::vector<ArchSpec> GetSupportedArchitectures() override;
|
||||
|
||||
bool CanDebugProcess() override;
|
||||
|
||||
|
@ -52,6 +52,8 @@ public:
|
|||
lldb::addr_t length, unsigned prot,
|
||||
unsigned flags, lldb::addr_t fd,
|
||||
lldb::addr_t offset) override;
|
||||
|
||||
std::vector<ArchSpec> m_supported_architectures;
|
||||
};
|
||||
|
||||
} // namespace platform_freebsd
|
||||
|
|
|
@ -109,78 +109,28 @@ void PlatformLinux::Terminate() {
|
|||
/// 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<ArchSpec> PlatformLinux::GetSupportedArchitectures() {
|
||||
if (m_remote_platform_sp)
|
||||
return m_remote_platform_sp->GetSupportedArchitectures();
|
||||
return m_supported_architectures;
|
||||
}
|
||||
|
||||
void PlatformLinux::GetStatus(Stream &strm) {
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
|
||||
void GetStatus(Stream &strm) override;
|
||||
|
||||
bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
|
||||
std::vector<ArchSpec> GetSupportedArchitectures() override;
|
||||
|
||||
uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override;
|
||||
|
||||
|
@ -57,6 +57,8 @@ public:
|
|||
lldb::addr_t length, unsigned prot,
|
||||
unsigned flags, lldb::addr_t fd,
|
||||
lldb::addr_t offset) override;
|
||||
|
||||
std::vector<ArchSpec> m_supported_architectures;
|
||||
};
|
||||
|
||||
} // namespace platform_linux
|
||||
|
|
|
@ -100,54 +100,24 @@ void PlatformNetBSD::Terminate() {
|
|||
/// 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<ArchSpec> PlatformNetBSD::GetSupportedArchitectures() {
|
||||
if (m_remote_platform_sp)
|
||||
return m_remote_platform_sp->GetSupportedArchitectures();
|
||||
return m_supported_architectures;
|
||||
}
|
||||
|
||||
void PlatformNetBSD::GetStatus(Stream &strm) {
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
|
||||
void GetStatus(Stream &strm) override;
|
||||
|
||||
bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
|
||||
std::vector<ArchSpec> GetSupportedArchitectures() override;
|
||||
|
||||
uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override;
|
||||
|
||||
|
@ -54,6 +54,8 @@ public:
|
|||
lldb::addr_t length, unsigned prot,
|
||||
unsigned flags, lldb::addr_t fd,
|
||||
lldb::addr_t offset) override;
|
||||
|
||||
std::vector<ArchSpec> m_supported_architectures;
|
||||
};
|
||||
|
||||
} // namespace platform_netbsd
|
||||
|
|
|
@ -1144,6 +1144,35 @@ Platform::GetPlatformForArchitecture(const ArchSpec &arch,
|
|||
return platform_sp;
|
||||
}
|
||||
|
||||
std::vector<ArchSpec>
|
||||
Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs,
|
||||
llvm::Triple::OSType os) {
|
||||
std::vector<ArchSpec> 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<ArchSpec> Platform::GetSupportedArchitectures() {
|
||||
std::vector<ArchSpec> 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,
|
||||
|
|
Loading…
Reference in New Issue