Platforms can now auto-select themselves if you specify a full target triple when doing a "target create" command.
Each platform now knows if it can handle an architecture and a platform can be found using an architecture. Each platform can look at the arch, vendor and OS and know if it should be used or not.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@153104 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp
index ac6fc20..b61acd7 100644
--- a/source/API/SBDebugger.cpp
+++ b/source/API/SBDebugger.cpp
@@ -612,11 +612,12 @@
Error error;
const bool add_dependent_modules = true;
+ PlatformSP platform_sp(m_opaque_sp->GetPlatformList().GetSelectedPlatform());
error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
file,
arch,
add_dependent_modules,
- m_opaque_sp->GetPlatformList().GetSelectedPlatform(),
+ platform_sp,
target_sp);
if (error.Success())
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index 855d8fb..9618c6c 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -63,7 +63,7 @@
const bool select = true;
m_platform_options.SetPlatformName (platform_name);
Error error;
- PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, select, error));
+ PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error));
if (platform_sp)
{
platform_sp->GetStatus (result.GetOutputStream());
diff --git a/source/Interpreter/OptionGroupPlatform.cpp b/source/Interpreter/OptionGroupPlatform.cpp
index 4e54c39..ca2f3ff 100644
--- a/source/Interpreter/OptionGroupPlatform.cpp
+++ b/source/Interpreter/OptionGroupPlatform.cpp
@@ -21,30 +21,36 @@
using namespace lldb_private;
PlatformSP
-OptionGroupPlatform::CreatePlatformWithOptions (CommandInterpreter &interpreter, bool make_selected, Error& error) const
+OptionGroupPlatform::CreatePlatformWithOptions (CommandInterpreter &interpreter, const ArchSpec &arch, bool make_selected, Error& error) const
{
PlatformSP platform_sp;
+
if (!m_platform_name.empty())
{
platform_sp = Platform::Create (m_platform_name.c_str(), error);
-
- if (platform_sp)
- {
- interpreter.GetDebugger().GetPlatformList().Append (platform_sp, make_selected);
- if (m_os_version_major != UINT32_MAX)
- {
- platform_sp->SetOSVersion (m_os_version_major,
- m_os_version_minor,
- m_os_version_update);
- }
-
- if (m_sdk_sysroot)
- platform_sp->SetSDKRootDirectory (m_sdk_sysroot);
-
- if (m_sdk_build)
- platform_sp->SetSDKBuild (m_sdk_build);
- }
}
+ else if (arch.IsValid())
+ {
+ platform_sp = Platform::Create (arch, error);
+ }
+
+ if (platform_sp)
+ {
+ interpreter.GetDebugger().GetPlatformList().Append (platform_sp, make_selected);
+ if (m_os_version_major != UINT32_MAX)
+ {
+ platform_sp->SetOSVersion (m_os_version_major,
+ m_os_version_minor,
+ m_os_version_update);
+ }
+
+ if (m_sdk_sysroot)
+ platform_sp->SetSDKRootDirectory (m_sdk_sysroot);
+
+ if (m_sdk_build)
+ platform_sp->SetSDKBuild (m_sdk_build);
+ }
+
return platform_sp;
}
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index ecc96c3..f64235d 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -25,9 +25,20 @@
using namespace lldb_private;
Platform *
-PlatformFreeBSD::CreateInstance ()
+PlatformFreeBSD::CreateInstance (bool force, const lldb_private::ArchSpec *arch)
{
- return new PlatformFreeBSD (true);
+ bool create = force;
+ if (create == false && arch && arch->IsValid())
+ {
+ const llvm::Triple &triple = arch->GetTriple();
+ const llvm::Triple::OSType os = triple.getOS();
+ if (os == llvm::Triple::FreeBSD || os == llvm::Triple::KFreeBSD)
+ create = true;
+ }
+ if (create)
+ return new PlatformFreeBSD (true);
+ return NULL;
+
}
const char *
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
index 438a0e6..80c4a63 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -25,7 +25,7 @@
// Class functions
//------------------------------------------------------------
static lldb_private::Platform*
- CreateInstance ();
+ CreateInstance (bool force, const lldb_private::ArchSpec *arch);
static void
Initialize ();
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp
index 80c9a86..58200da 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -33,9 +33,19 @@
static uint32_t g_initialize_count = 0;
Platform *
-PlatformLinux::CreateInstance ()
+PlatformLinux::CreateInstance (bool force, const ArchSpec *arch)
{
- return new PlatformLinux(true);
+ bool create = force;
+ if (create == false && arch && arch->IsValid())
+ {
+ const llvm::Triple &triple = arch->GetTriple();
+ const llvm::Triple::OSType os = triple.getOS();
+ if (os == llvm::Triple::Linux)
+ create = true;
+ }
+ if (create)
+ return new PlatformLinux(true);
+ return NULL;
}
const char *
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.h b/source/Plugins/Platform/Linux/PlatformLinux.h
index 59dde3e..8b43def 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.h
+++ b/source/Plugins/Platform/Linux/PlatformLinux.h
@@ -37,7 +37,7 @@
// lldb_private::PluginInterface functions
//------------------------------------------------------------
static Platform *
- CreateInstance ();
+ CreateInstance (bool force, const lldb_private::ArchSpec *arch);
static const char *
GetPluginNameStatic();
diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index 6262c59..f7c2374 100644
--- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -61,12 +61,24 @@
}
Platform*
-PlatformMacOSX::CreateInstance ()
+PlatformMacOSX::CreateInstance (bool force, const ArchSpec *arch)
{
// The only time we create an instance is when we are creating a remote
// macosx platform
const bool is_host = false;
- return new PlatformMacOSX (is_host);
+
+ bool create = force;
+ if (create == false && arch && arch->IsValid())
+ {
+ const llvm::Triple &triple = arch->GetTriple();
+ const llvm::Triple::OSType os = triple.getOS();
+ const llvm::Triple::VendorType vendor = triple.getVendor();
+ if (os == llvm::Triple::Darwin && vendor == llvm::Triple::Apple)
+ create = true;
+ }
+ if (create)
+ return new PlatformMacOSX (is_host);
+ return NULL;
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
index 4a47b7f..3a5eaf0 100644
--- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
+++ b/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
@@ -24,7 +24,7 @@
// Class functions
//------------------------------------------------------------
static lldb_private::Platform*
- CreateInstance ();
+ CreateInstance (bool force, const lldb_private::ArchSpec *arch);
static void
Initialize ();
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index ad49573..61caafc 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -60,9 +60,31 @@
}
Platform*
-PlatformRemoteiOS::CreateInstance ()
+PlatformRemoteiOS::CreateInstance (bool force, const ArchSpec *arch)
{
- return new PlatformRemoteiOS ();
+ bool create = force;
+ if (create == false && arch && arch->IsValid())
+ {
+ switch (arch->GetMachine())
+ {
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ {
+ const llvm::Triple &triple = arch->GetTriple();
+ const llvm::Triple::OSType os = triple.getOS();
+ const llvm::Triple::VendorType vendor = triple.getVendor();
+ if (os == llvm::Triple::Darwin && vendor == llvm::Triple::Apple)
+ create = true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (create)
+ return new PlatformRemoteiOS ();
+ return NULL;
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
index 9aa33f8..051b584 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
@@ -24,7 +24,7 @@
// Class Functions
//------------------------------------------------------------
static lldb_private::Platform*
- CreateInstance ();
+ CreateInstance (bool force, const lldb_private::ArchSpec *arch);
static void
Initialize ();
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
index 18cd4eb..7a8884e 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
@@ -60,9 +60,30 @@
}
Platform*
-PlatformiOSSimulator::CreateInstance ()
+PlatformiOSSimulator::CreateInstance (bool force, const ArchSpec *arch)
{
- return new PlatformiOSSimulator ();
+ bool create = force;
+ if (create == false && arch && arch->IsValid())
+ {
+ switch (arch->GetMachine())
+ {
+ // Currently simulator is i386 only...
+ case llvm::Triple::x86:
+ {
+ const llvm::Triple &triple = arch->GetTriple();
+ const llvm::Triple::OSType os = triple.getOS();
+ const llvm::Triple::VendorType vendor = triple.getVendor();
+ if (os == llvm::Triple::Darwin && vendor == llvm::Triple::Apple)
+ create = true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (create)
+ return new PlatformiOSSimulator ();
+ return NULL;
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
index d098642..3973c2f 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
@@ -24,7 +24,7 @@
// Class Functions
//------------------------------------------------------------
static lldb_private::Platform*
- CreateInstance ();
+ CreateInstance (bool force, const lldb_private::ArchSpec *arch);
static void
Initialize ();
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 248475a..4d9cd96 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -56,7 +56,7 @@
}
Platform*
-PlatformRemoteGDBServer::CreateInstance ()
+PlatformRemoteGDBServer::CreateInstance (bool force, const lldb_private::ArchSpec *arch)
{
return new PlatformRemoteGDBServer ();
}
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 48f3613..ad2ffa5 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -30,7 +30,7 @@
Terminate ();
static lldb_private::Platform*
- CreateInstance ();
+ CreateInstance (bool force, const lldb_private::ArchSpec *arch);
static const char *
GetShortPluginNameStatic();
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 403b10e..cc8070d 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -110,7 +110,6 @@
always_create);
}
-
PlatformSP
Platform::Create (const char *platform_name, Error &error)
{
@@ -120,7 +119,7 @@
{
create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
if (create_callback)
- platform_sp.reset(create_callback());
+ platform_sp.reset(create_callback(true, NULL));
else
error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
}
@@ -129,6 +128,27 @@
return platform_sp;
}
+
+PlatformSP
+Platform::Create (const ArchSpec &arch, Error &error)
+{
+ lldb::PlatformSP platform_sp;
+ if (arch.IsValid())
+ {
+ PlatformCreateInstance create_callback;
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
+ {
+ if (create_callback)
+ platform_sp.reset(create_callback(false, &arch));
+ if (platform_sp && platform_sp->IsCompatibleWithArchitecture(arch))
+ break;
+ }
+ }
+ else
+ error.SetErrorString ("invalid platform name");
+ return platform_sp;
+}
+
uint32_t
Platform::GetNumConnectedRemotePlatforms ()
{
@@ -592,3 +612,38 @@
}
return process_sp;
}
+
+
+lldb::PlatformSP
+Platform::GetPlatformForArchitecture (const ArchSpec &arch)
+{
+ lldb::PlatformSP platform_sp;
+ Error error;
+ if (arch.IsValid())
+ platform_sp = Platform::Create (arch, error);
+ return platform_sp;
+}
+
+
+//------------------------------------------------------------------
+/// Lets a platform answer if it is compatible with a given
+/// architecture and the target triple contained within.
+//------------------------------------------------------------------
+bool
+Platform::IsCompatibleWithArchitecture (const ArchSpec &arch)
+{
+ // If the architecture is invalid, we must answer true...
+ if (!arch.IsValid())
+ return true;
+
+ ArchSpec platform_arch;
+ for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
+ {
+ if (arch == platform_arch)
+ return true;
+ }
+ return false;
+
+}
+
+
diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp
index 38240e1..d987913 100644
--- a/source/Target/TargetList.cpp
+++ b/source/Target/TargetList.cpp
@@ -17,6 +17,7 @@
#include "lldb/Core/State.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
@@ -63,22 +64,7 @@
{
Error error;
PlatformSP platform_sp;
- if (platform_options)
- {
- if (platform_options->PlatformWasSpecified ())
- {
- const bool select_platform = true;
- platform_sp = platform_options->CreatePlatformWithOptions (debugger.GetCommandInterpreter(),
- select_platform,
- error);
- if (!platform_sp)
- return error;
- }
- }
- if (!platform_sp)
- platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
-
// This is purposely left empty unless it is specified by triple_cstr.
// If not initialized via triple_cstr, then the currently selected platform
// will set the architecture correctly.
@@ -93,6 +79,34 @@
return error;
}
}
+
+ CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
+ if (platform_options)
+ {
+ if (platform_options->PlatformWasSpecified ())
+ {
+ const bool select_platform = true;
+ platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
+ arch,
+ select_platform,
+ error);
+ if (!platform_sp)
+ return error;
+ }
+ }
+
+ if (!platform_sp)
+ {
+ // Get the current platform and make sure it is compatible with the
+ // current architecture if we have a valid architecture.
+ platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
+
+ if (arch.IsValid() && !platform_sp->IsCompatibleWithArchitecture(arch))
+ {
+ platform_sp = Platform::GetPlatformForArchitecture(arch);
+ }
+ }
+
error = TargetList::CreateTarget (debugger,
file,
arch,
@@ -119,7 +133,7 @@
const FileSpec& file,
const ArchSpec& arch,
bool get_dependent_files,
- const PlatformSP &platform_sp,
+ PlatformSP &platform_sp,
TargetSP &target_sp
)
{
@@ -142,6 +156,13 @@
error = platform_sp->ResolveExecutable (file, arch,
exe_module_sp,
executable_search_paths.GetSize() ? &executable_search_paths : NULL);
+
+ if (exe_module_sp)
+ {
+ const ArchSpec &arch = exe_module_sp->GetArchitecture();
+ if (arch.IsValid() && !platform_sp->IsCompatibleWithArchitecture(arch))
+ platform_sp = Platform::GetPlatformForArchitecture(arch);
+ }
}
if (error.Success() && exe_module_sp)
diff --git a/source/lldb.cpp b/source/lldb.cpp
index 3c7b768..fb377b2 100644
--- a/source/lldb.cpp
+++ b/source/lldb.cpp
@@ -126,8 +126,8 @@
ProcessGDBRemote::Initialize();
ProcessMachCore::Initialize();
SymbolVendorMacOSX::Initialize();
- PlatformMacOSX::Initialize();
PlatformRemoteiOS::Initialize();
+ PlatformMacOSX::Initialize();
PlatformiOSSimulator::Initialize();
#endif
#if defined (__linux__)