Added new platform commands:
platform connect <args>
platform disconnect
Each platform can decide the args they want to use for "platform connect". I
will need to add a function that gets the connect options for the current
platform as each one can have different options and argument counts.
Hooked up more functionality in the PlatformMacOSX and PlatformRemoteiOS.
Also started an platform agnostic PlatformRemoteGDBServer.cpp which can end
up being used by one or more actual platforms. It can also be specialized and
allow for platform specific commands.
llvm-svn: 128123
diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp
index 97eb0a4..dc6b4ef 100644
--- a/lldb/source/Commands/CommandObjectPlatform.cpp
+++ b/lldb/source/Commands/CommandObjectPlatform.cpp
@@ -281,6 +281,137 @@
};
+//----------------------------------------------------------------------
+// "platform connect <connect-url>"
+//----------------------------------------------------------------------
+class CommandObjectPlatformConnect : public CommandObject
+{
+public:
+ CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
+ CommandObject (interpreter,
+ "platform connect",
+ "Connect a platform by name to be the currently selected platform.",
+ "platform connect <connect-url>",
+ 0)
+ {
+ }
+
+ virtual
+ ~CommandObjectPlatformConnect ()
+ {
+ }
+
+ virtual bool
+ Execute (Args& args, CommandReturnObject &result)
+ {
+ Stream &ostrm = result.GetOutputStream();
+
+ // Get rid of the "connect" from the args and leave the rest to the platform
+ args.Shift();
+ PlatformSP selected_platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (selected_platform_sp)
+ {
+ Error error (selected_platform_sp->ConnectRemote (args));
+ if (error.Success())
+ {
+ ostrm.Printf ("Connected to \"%s\"\n", selected_platform_sp->GetInstanceName());
+ selected_platform_sp->GetStatus (ostrm);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("connection failed: %s", error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ result.AppendError ("no platform us currently selected");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+};
+
+//----------------------------------------------------------------------
+// "platform disconnect"
+//----------------------------------------------------------------------
+class CommandObjectPlatformDisconnect : public CommandObject
+{
+public:
+ CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
+ CommandObject (interpreter,
+ "platform disconnect",
+ "Disconnect a platform by name to be the currently selected platform.",
+ "platform disconnect",
+ 0)
+ {
+ }
+
+ virtual
+ ~CommandObjectPlatformDisconnect ()
+ {
+ }
+
+ virtual bool
+ Execute (Args& args, CommandReturnObject &result)
+ {
+ PlatformSP selected_platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (selected_platform_sp)
+ {
+ if (args.GetArgumentCount() == 0)
+ {
+ Error error;
+
+ if (selected_platform_sp->IsConnected())
+ {
+ // Cache the instance name if there is one since we are
+ // about to disconnect and the name might go with it.
+ const char *instance_name_cstr = selected_platform_sp->GetInstanceName();
+ std::string instance_name;
+ if (instance_name_cstr)
+ instance_name.assign (instance_name_cstr);
+
+ error = selected_platform_sp->DisconnectRemote ();
+ if (error.Success())
+ {
+ Stream &ostrm = result.GetOutputStream();
+ if (instance_name.empty())
+ ostrm.Printf ("Disconnected from \"%s\"\n", selected_platform_sp->GetShortPluginName());
+ else
+ ostrm.Printf ("Disconnected from \"%s\"\n", instance_name.c_str());
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("disconnect failed: %s", error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ // Not connected...
+ result.AppendError ("not connected.");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ // Bad args
+ result.AppendError ("\"platform disconnect\" doesn't take any arguments");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ result.AppendError ("no platform us currently selected");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+};
+
+
//----------------------------------------------------------------------
// CommandObjectPlatform constructor
@@ -289,12 +420,14 @@
CommandObjectMultiword (interpreter,
"platform",
"A set of commands to manage and create platforms.",
- "platform [create|list|status|select] ...")
+ "platform [connect|create|disconnect|list|status|select] ...")
{
LoadSubCommand ("create", CommandObjectSP (new CommandObjectPlatformCreate (interpreter)));
LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
+ LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
+ LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index 8c1ef1d..ba7be39 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -1,4 +1,4 @@
-//===-- Platform.cpp --------------------------------------------*- C++ -*-===//
+//===-- PlatformMacOSX.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -138,7 +138,9 @@
}
Error
-PlatformMacOSX::GetFile (const FileSpec &platform_file, FileSpec &local_file)
+PlatformMacOSX::GetFile (const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file)
{
// Default to the local case
local_file = platform_file;
@@ -193,11 +195,7 @@
/// Default Constructor
//------------------------------------------------------------------
PlatformMacOSX::PlatformMacOSX () :
-#if defined (__APPLE__)
Platform(true) // This is the local host platform
-#else
- Platform(false) // This is a remote platform
-#endif
{
}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
index 4b0db15..b0e3d1a 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
@@ -73,7 +73,9 @@
GetStatus (Stream &strm);
virtual Error
- GetFile (const FileSpec &platform_file, FileSpec &local_file);
+ GetFile (const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file);
virtual uint32_t
FindProcessesByName (const char *name_match,
@@ -96,4 +98,4 @@
};
} // namespace lldb_private
-#endif // liblldb_Platform_h_
+#endif // liblldb_PlatformMacOSX_h_
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index c0bece1..fa6fcdc 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -1,4 +1,4 @@
-//===-- Platform.cpp --------------------------------------------*- C++ -*-===//
+//===-- PlatformRemoteiOS.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -27,18 +27,28 @@
using namespace lldb;
using namespace lldb_private;
+
+static bool g_initialized = false;
void
PlatformRemoteiOS::Initialize ()
{
- static bool g_initialized = false;
-
if (g_initialized == false)
{
g_initialized = true;
- PluginManager::RegisterPlugin (GetShortPluginNameStatic(),
- GetDescriptionStatic(),
- CreateInstance);
+ PluginManager::RegisterPlugin (PlatformRemoteiOS::GetShortPluginNameStatic(),
+ PlatformRemoteiOS::GetDescriptionStatic(),
+ PlatformRemoteiOS::CreateInstance);
+ }
+}
+
+void
+PlatformRemoteiOS::Terminate ()
+{
+ if (g_initialized)
+ {
+ g_initialized = false;
+ PluginManager::UnregisterPlugin (PlatformRemoteiOS::CreateInstance);
}
}
@@ -48,10 +58,6 @@
return new PlatformRemoteiOS ();
}
-void
-PlatformRemoteiOS::Terminate ()
-{
-}
const char *
PlatformRemoteiOS::GetPluginNameStatic ()
@@ -358,6 +364,7 @@
Error
PlatformRemoteiOS::GetFile (const FileSpec &platform_file,
+ const UUID *uuid_ptr,
FileSpec &local_file)
{
Error error;
@@ -442,6 +449,29 @@
return false;
}
+const char *
+PlatformRemoteiOS::GetRemoteInstanceName ()
+{
+ if (m_remote_instance_name.empty())
+ {
+ const char *device_support_dir = GetDeviceSupportDirectory();
+ if (device_support_dir)
+ {
+ std::string latest_device_support_dir;
+ latest_device_support_dir.assign (device_support_dir);
+ latest_device_support_dir.append ("/Platforms/iPhoneOS.platform/DeviceSupport/Latest");
+ const bool resolve_path = true;
+ FileSpec file_spec (m_device_support_directory_for_os_version.c_str(), resolve_path);
+ // We are using the resolved basename of the "Latest" symlink (which
+ // is usually the latest and greatest SDK version and the update
+ // which is something like: "4.0 (8A123)"
+ if (file_spec.Exists())
+ m_remote_instance_name.assign (file_spec.GetFilename().GetCString());
+ }
+ }
+ return m_remote_instance_name.c_str();
+}
+
bool
PlatformRemoteiOS::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
@@ -549,6 +579,13 @@
return false;
}
+bool
+PlatformRemoteiOS::FetchRemoteOSVersion ()
+{
+ return false;
+}
+
+
size_t
PlatformRemoteiOS::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
{
@@ -610,3 +647,35 @@
return 0;
}
+
+Error
+PlatformRemoteiOS::ConnectRemote (Args& args)
+{
+ Error error;
+ error.SetErrorStringWithFormat ("'platform connect' is not implemented yet for platform '%s'", GetShortPluginNameStatic());
+
+// if (args.GetArgumentCount() == 1)
+// {
+// const char *remote_url = args.GetArgumentAtIndex(0);
+// ConnectionStatus status = m_gdb_client.Connect(remote_url, &error);
+// if (status == eConnectionStatusSuccess)
+// {
+// m_gdb_client.GetHostInfo();
+// }
+// }
+// else
+// {
+// error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
+// }
+
+ return error;
+}
+
+Error
+PlatformRemoteiOS::DisconnectRemote ()
+{
+ Error error;
+ error.SetErrorStringWithFormat ("'platform disconnect' is not implemented yet for platform '%s'", GetShortPluginNameStatic());
+// m_gdb_client.Disconnect(&error);
+ return error;
+}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
index 5c0f075..36f4c00 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
@@ -85,7 +85,9 @@
GetStatus (Stream &strm);
virtual Error
- GetFile (const FileSpec &platform_file, FileSpec &local_file);
+ GetFile (const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file);
virtual uint32_t
FindProcessesByName (const char *name_match,
@@ -102,6 +104,19 @@
GetSoftwareBreakpointTrapOpcode (Target &target,
BreakpointSite *bp_site);
+ virtual bool
+ FetchRemoteOSVersion ();
+
+ virtual Error
+ ConnectRemote (Args& args);
+
+ virtual Error
+ DisconnectRemote ();
+
+ virtual const char *
+ GetRemoteInstanceName ();
+
+
protected:
std::string m_device_support_directory;
std::string m_device_support_directory_for_os_version;
@@ -120,4 +135,4 @@
};
} // namespace lldb_private
-#endif // liblldb_Platform_h_
+#endif // liblldb_PlatformRemoteiOS_h_
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
new file mode 100644
index 0000000..f8a73a3
--- /dev/null
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -0,0 +1,240 @@
+//===-- PlatformRemoteGDBServer.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PlatformRemoteGDBServer.h"
+
+// C Includes
+#include <sys/sysctl.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Error.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static bool g_initialized = false;
+
+void
+PlatformRemoteGDBServer::Initialize ()
+{
+ if (g_initialized == false)
+ {
+ g_initialized = true;
+ PluginManager::RegisterPlugin (PlatformRemoteGDBServer::GetShortPluginNameStatic(),
+ PlatformRemoteGDBServer::GetDescriptionStatic(),
+ PlatformRemoteGDBServer::CreateInstance);
+ }
+}
+
+void
+PlatformRemoteGDBServer::Terminate ()
+{
+ if (g_initialized)
+ {
+ g_initialized = false;
+ PluginManager::UnregisterPlugin (PlatformRemoteGDBServer::CreateInstance);
+ }
+}
+
+Platform*
+PlatformRemoteGDBServer::CreateInstance ()
+{
+ return new PlatformRemoteGDBServer ();
+}
+
+const char *
+PlatformRemoteGDBServer::GetShortPluginNameStatic()
+{
+ return "remote-gdb-server";
+}
+
+const char *
+PlatformRemoteGDBServer::GetDescriptionStatic()
+{
+ return "A platform that uses the GDB remote protocol as the communication transport.";
+}
+
+const char *
+PlatformRemoteGDBServer::GetDescription ()
+{
+ if (m_platform_description.empty())
+ {
+ if (IsConnected())
+ {
+ // Send the get description packet
+ }
+ }
+
+ if (!m_platform_description.empty())
+ return m_platform_description.c_str();
+ return GetDescriptionStatic();
+}
+
+Error
+PlatformRemoteGDBServer::ResolveExecutable (const FileSpec &exe_file,
+ const ArchSpec &exe_arch,
+ lldb::ModuleSP &exe_module_sp)
+{
+ Error error;
+ error.SetErrorString ("PlatformRemoteGDBServer::ResolveExecutable() is unimplemented");
+ return error;
+}
+
+Error
+PlatformRemoteGDBServer::GetFile (const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file)
+{
+ // Default to the local case
+ local_file = platform_file;
+ return Error();
+}
+
+
+void
+PlatformRemoteGDBServer::GetStatus (Stream &strm)
+{
+ char sysctlstring[1024];
+ size_t datalen;
+ int mib[CTL_MAXNAME];
+
+ uint32_t major = UINT32_MAX;
+ uint32_t minor = UINT32_MAX;
+ uint32_t update = UINT32_MAX;
+ strm.PutCString("Remote GDB server platform");
+ if (GetOSVersion(major, minor, update))
+ {
+ strm.Printf("OS version: %u", major);
+ if (minor != UINT32_MAX)
+ strm.Printf(".%u", minor);
+ if (update != UINT32_MAX)
+ strm.Printf(".%u", update);
+
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_OSVERSION;
+ datalen = sizeof(sysctlstring);
+ if (::sysctl (mib, 2, sysctlstring, &datalen, NULL, 0) == 0)
+ {
+ sysctlstring[datalen] = '\0';
+ strm.Printf(" (%s)", sysctlstring);
+ }
+
+ strm.EOL();
+ }
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_VERSION;
+ datalen = sizeof(sysctlstring);
+ if (::sysctl (mib, 2, sysctlstring, &datalen, NULL, 0) == 0)
+ {
+ sysctlstring[datalen] = '\0';
+ strm.Printf("Kernel version: %s\n", sysctlstring);
+ }
+}
+
+
+//------------------------------------------------------------------
+/// Default Constructor
+//------------------------------------------------------------------
+PlatformRemoteGDBServer::PlatformRemoteGDBServer () :
+ Platform(false) // This is a remote platform
+{
+}
+
+//------------------------------------------------------------------
+/// Destructor.
+///
+/// The destructor is virtual since this class is designed to be
+/// inherited from by the plug-in instance.
+//------------------------------------------------------------------
+PlatformRemoteGDBServer::~PlatformRemoteGDBServer()
+{
+}
+
+uint32_t
+PlatformRemoteGDBServer::FindProcessesByName (const char *name_match,
+ lldb::NameMatchType name_match_type,
+ ProcessInfoList &process_infos)
+{
+ return 0;
+}
+
+bool
+PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
+{
+ return false;
+}
+
+bool
+PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
+{
+ return false;
+}
+
+size_t
+PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
+{
+ // This isn't needed if the z/Z packets are supported in the GDB remote
+ // server. But we might need a packet to detect this.
+ return 0;
+}
+
+bool
+PlatformRemoteGDBServer::FetchRemoteOSVersion ()
+{
+ return false;
+}
+
+Error
+PlatformRemoteGDBServer::ConnectRemote (Args& args)
+{
+ Error error;
+ if (args.GetArgumentCount() == 1)
+ {
+ const char *remote_url = args.GetArgumentAtIndex(0);
+ ConnectionStatus status = m_gdb_client.Connect(remote_url, &error);
+ if (status == eConnectionStatusSuccess)
+ {
+ m_gdb_client.GetHostInfo();
+ }
+ }
+ else
+ {
+ error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
+ }
+
+ return error;
+}
+
+Error
+PlatformRemoteGDBServer::DisconnectRemote ()
+{
+ Error error;
+ m_gdb_client.Disconnect(&error);
+ return error;
+}
+
+const char *
+PlatformRemoteGDBServer::GetRemoteInstanceName ()
+{
+ return NULL;
+}
+
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
new file mode 100644
index 0000000..6c322d3
--- /dev/null
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -0,0 +1,127 @@
+//===-- PlatformRemoteGDBServer.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_PlatformRemoteGDBServer_h_
+#define liblldb_PlatformRemoteGDBServer_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/Platform.h"
+#include "../../Process/gdb-remote/GDBRemoteCommunicationClient.h"
+
+namespace lldb_private {
+
+ class PlatformRemoteGDBServer : public Platform
+ {
+ public:
+
+ static void
+ Initialize ();
+
+ static void
+ Terminate ();
+
+ static Platform*
+ CreateInstance ();
+
+ static const char *
+ GetShortPluginNameStatic();
+
+ static const char *
+ GetDescriptionStatic();
+
+
+ PlatformRemoteGDBServer ();
+
+ virtual
+ ~PlatformRemoteGDBServer();
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ virtual const char *
+ GetPluginName()
+ {
+ return "PlatformRemoteGDBServer";
+ }
+
+ virtual const char *
+ GetShortPluginName()
+ {
+ return GetShortPluginNameStatic();
+ }
+
+ virtual uint32_t
+ GetPluginVersion()
+ {
+ return 1;
+ }
+
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+ virtual Error
+ ResolveExecutable (const FileSpec &exe_file,
+ const ArchSpec &arch,
+ lldb::ModuleSP &module_sp);
+
+ virtual const char *
+ GetDescription ();
+
+ virtual void
+ GetStatus (Stream &strm);
+
+ virtual Error
+ GetFile (const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file);
+
+ virtual uint32_t
+ FindProcessesByName (const char *name_match,
+ lldb::NameMatchType name_match_type,
+ ProcessInfoList &process_infos);
+
+ virtual bool
+ GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc_info);
+
+ virtual bool
+ GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch);
+
+ virtual size_t
+ GetSoftwareBreakpointTrapOpcode (Target &target,
+ BreakpointSite *bp_site);
+
+ virtual bool
+ FetchRemoteOSVersion ();
+
+ virtual Error
+ ConnectRemote (Args& args);
+
+ virtual Error
+ DisconnectRemote ();
+
+ virtual const char *
+ GetRemoteInstanceName ();
+
+ protected:
+ GDBRemoteCommunicationClient m_gdb_client;
+ std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN (PlatformRemoteGDBServer);
+
+ };
+} // namespace lldb_private
+
+#endif // liblldb_PlatformRemoteGDBServer_h_
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index b4fb6f2..7700ab2 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -50,11 +50,7 @@
m_async_packet (),
m_async_response (),
m_async_signal (-1),
- m_arch(),
- m_os(),
- m_vendor(),
- m_byte_order(lldb::endian::InlHostByteOrder()),
- m_pointer_byte_size(0)
+ m_host_arch()
{
m_rx_packet_listener.StartListeningForEvents(this,
Communication::eBroadcastBitPacketAvailable |
@@ -102,11 +98,7 @@
m_supports_vCont_C = eLazyBoolCalculate;
m_supports_vCont_s = eLazyBoolCalculate;
m_supports_vCont_S = eLazyBoolCalculate;
- m_arch.Clear();
- m_os.Clear();
- m_vendor.Clear();
- m_byte_order = lldb::endian::InlHostByteOrder();
- m_pointer_byte_size = 0;
+ m_host_arch.Clear();
}
@@ -690,7 +682,11 @@
std::string value;
uint32_t cpu = LLDB_INVALID_CPUTYPE;
uint32_t sub = 0;
-
+ std::string arch_name;
+ std::string os_name;
+ std::string vendor_name;
+ uint32_t pointer_byte_size = 0;
+ ByteOrder byte_order = eByteOrderInvalid;
while (response.GetNameColonValue(name, value))
{
if (name.compare("cputype") == 0)
@@ -703,32 +699,69 @@
// exception count in big endian hex
sub = Args::StringToUInt32 (value.c_str(), 0, 0);
}
+ else if (name.compare("arch") == 0)
+ {
+ arch_name.swap (value);
+ }
else if (name.compare("ostype") == 0)
{
- // exception data in big endian hex
- m_os.SetCString(value.c_str());
+ os_name.swap (value);
}
else if (name.compare("vendor") == 0)
{
- m_vendor.SetCString(value.c_str());
+ vendor_name.swap(value);
}
else if (name.compare("endian") == 0)
{
if (value.compare("little") == 0)
- m_byte_order = eByteOrderLittle;
+ byte_order = eByteOrderLittle;
else if (value.compare("big") == 0)
- m_byte_order = eByteOrderBig;
+ byte_order = eByteOrderBig;
else if (value.compare("pdp") == 0)
- m_byte_order = eByteOrderPDP;
+ byte_order = eByteOrderPDP;
}
else if (name.compare("ptrsize") == 0)
{
- m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+ pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
}
}
- if (cpu != LLDB_INVALID_CPUTYPE)
- m_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
+ if (arch_name.empty())
+ {
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ {
+ m_host_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
+ if (pointer_byte_size)
+ {
+ assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
+ }
+ if (byte_order != eByteOrderInvalid)
+ {
+ assert (byte_order == m_host_arch.GetByteOrder());
+ }
+ if (!vendor_name.empty())
+ m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
+ if (!os_name.empty())
+ m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
+
+ }
+ }
+ else
+ {
+ std::string triple;
+ triple += arch_name;
+ triple += '-';
+ if (vendor_name.empty())
+ triple += "unknown";
+ else
+ triple += vendor_name;
+ triple += '-';
+ if (os_name.empty())
+ triple += "unknown";
+ else
+ triple += os_name;
+ m_host_arch.SetTriple (triple.c_str());
+ }
}
}
return m_supports_qHostInfo == eLazyBoolYes;
@@ -759,41 +792,9 @@
const lldb_private::ArchSpec &
GDBRemoteCommunicationClient::GetHostArchitecture ()
{
- if (!HostInfoIsValid ())
+ if (m_supports_qHostInfo == lldb::eLazyBoolCalculate)
GetHostInfo ();
- return m_arch;
-}
-
-const lldb_private::ConstString &
-GDBRemoteCommunicationClient::GetOSString ()
-{
- if (!HostInfoIsValid ())
- GetHostInfo ();
- return m_os;
-}
-
-const lldb_private::ConstString &
-GDBRemoteCommunicationClient::GetVendorString()
-{
- if (!HostInfoIsValid ())
- GetHostInfo ();
- return m_vendor;
-}
-
-lldb::ByteOrder
-GDBRemoteCommunicationClient::GetByteOrder ()
-{
- if (!HostInfoIsValid ())
- GetHostInfo ();
- return m_byte_order;
-}
-
-uint32_t
-GDBRemoteCommunicationClient::GetAddressByteSize ()
-{
- if (!HostInfoIsValid ())
- GetHostInfo ();
- return m_pointer_byte_size;
+ return m_host_arch;
}
addr_t
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 604e09a..bcf23f2 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -176,18 +176,6 @@
const lldb_private::ArchSpec &
GetHostArchitecture ();
- const lldb_private::ConstString &
- GetOSString ();
-
- const lldb_private::ConstString &
- GetVendorString();
-
- lldb::ByteOrder
- GetByteOrder ();
-
- uint32_t
- GetAddressByteSize ();
-
bool
GetVContSupported (char flavor);
@@ -222,12 +210,6 @@
protected:
- bool
- HostInfoIsValid () const
- {
- return m_supports_qHostInfo != lldb::eLazyBoolCalculate;
- }
-
//------------------------------------------------------------------
// Classes that inherit from GDBRemoteCommunicationClient can see and modify these
//------------------------------------------------------------------
@@ -249,14 +231,8 @@
StringExtractorGDBRemote m_async_response;
int m_async_signal; // We were asked to deliver a signal to the inferior process.
- lldb_private::ArchSpec m_arch;
+ lldb_private::ArchSpec m_host_arch;
uint32_t m_cpusubtype;
- lldb_private::ConstString m_os;
- lldb_private::ConstString m_vendor;
- lldb::ByteOrder m_byte_order;
- uint32_t m_pointer_byte_size;
-
-
private:
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 2e4ff70..18d6087 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -72,10 +72,12 @@
//}
//
bool
-GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout_time_ptr)
+GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout_ptr,
+ bool &interrupt,
+ bool &quit)
{
StringExtractorGDBRemote packet;
- if (WaitForPacketNoLock (packet, timeout_time_ptr))
+ if (WaitForPacketNoLock (packet, timeout_ptr))
{
const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
switch (packet_type)
@@ -85,6 +87,13 @@
break;
case StringExtractorGDBRemote::eServerPacketType_invalid:
+ quit = true;
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_interrupt:
+ interrupt = true;
+ break;
+
case StringExtractorGDBRemote::eServerPacketType_unimplemented:
return SendUnimplementedResponse () > 0;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 8ccfca2..4e0b24d 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -34,7 +34,9 @@
~GDBRemoteCommunicationServer();
bool
- GetPacketAndSendResponse (const lldb_private::TimeValue* timeout_time_ptr);
+ GetPacketAndSendResponse (const lldb_private::TimeValue* timeout_ptr,
+ bool &interrupt,
+ bool &quit);
virtual bool
GetThreadSuffixSupported ()
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 7994966..e5a1d7c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -622,34 +622,52 @@
BuildDynamicRegisterInfo (false);
- m_target.GetArchitecture().SetByteOrder (m_gdb_comm.GetByteOrder());
StreamString strm;
// See if the GDB server supports the qHostInfo information
- const char *vendor = m_gdb_comm.GetVendorString().AsCString();
- const char *os_type = m_gdb_comm.GetOSString().AsCString();
- ArchSpec target_arch (GetTarget().GetArchitecture());
- ArchSpec gdb_remote_arch (m_gdb_comm.GetHostArchitecture());
- // If the remote host is ARM and we have apple as the vendor, then
- // ARM executables and shared libraries can have mixed ARM architectures.
- // You can have an armv6 executable, and if the host is armv7, then the
- // system will load the best possible architecture for all shared libraries
- // it has, so we really need to take the remote host architecture as our
- // defacto architecture in this case.
-
- if (gdb_remote_arch.GetMachine() == llvm::Triple::arm &&
- gdb_remote_arch.GetTriple().getVendor() == llvm::Triple::Apple)
+ const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
+ if (gdb_remote_arch.IsValid())
{
- GetTarget().SetArchitecture (gdb_remote_arch);
- target_arch = gdb_remote_arch;
+ ArchSpec &target_arch = GetTarget().GetArchitecture();
+
+ if (target_arch.IsValid())
+ {
+ // If the remote host is ARM and we have apple as the vendor, then
+ // ARM executables and shared libraries can have mixed ARM architectures.
+ // You can have an armv6 executable, and if the host is armv7, then the
+ // system will load the best possible architecture for all shared libraries
+ // it has, so we really need to take the remote host architecture as our
+ // defacto architecture in this case.
+
+ if (gdb_remote_arch.GetMachine() == llvm::Triple::arm &&
+ gdb_remote_arch.GetTriple().getVendor() == llvm::Triple::Apple)
+ {
+ target_arch = gdb_remote_arch;
+ }
+ else
+ {
+ // Fill in what is missing in the triple
+ const llvm::Triple &remote_triple = gdb_remote_arch.GetTriple();
+ llvm::Triple &target_triple = target_arch.GetTriple();
+ if (target_triple.getVendor() == llvm::Triple::UnknownVendor)
+ target_triple.setVendor (remote_triple.getVendor());
+
+ if (target_triple.getOS() == llvm::Triple::UnknownOS)
+ target_triple.setOS (remote_triple.getOS());
+
+ if (target_triple.getEnvironment() == llvm::Triple::UnknownEnvironment)
+ target_triple.setEnvironment (remote_triple.getEnvironment());
+ }
+ }
+ else
+ {
+ // The target doesn't have a valid architecture yet, set it from
+ // the architecture we got from the remote GDB server
+ target_arch = gdb_remote_arch;
+ }
}
-
- if (vendor)
- m_target.GetArchitecture().GetTriple().setVendorName(vendor);
- if (os_type)
- m_target.GetArchitecture().GetTriple().setOSName(os_type);
}
}
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 32ac194..a6df50d 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -69,7 +69,9 @@
}
Error
-Platform::GetFile (const FileSpec &platform_file, FileSpec &local_file)
+Platform::GetFile (const FileSpec &platform_file,
+ const UUID *uuid_ptr,
+ FileSpec &local_file)
{
// Default to the local case
local_file = platform_file;
@@ -123,6 +125,7 @@
m_os_version_set_while_connected (false),
m_system_arch_set_while_connected (false),
m_remote_url (),
+ m_remote_instance_name (),
m_major_os_version (UINT32_MAX),
m_minor_os_version (UINT32_MAX),
m_update_os_version (UINT32_MAX)
@@ -330,17 +333,23 @@
Error
-Platform::ConnectRemote (const char *remote_url)
+Platform::ConnectRemote (Args& args)
{
Error error;
- error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
+ if (IsHost())
+ error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
+ else
+ error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
return error;
}
Error
-Platform::DisconnectRemote (const lldb::PlatformSP &platform_sp)
+Platform::DisconnectRemote ()
{
Error error;
- error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
+ if (IsHost())
+ error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
+ else
+ error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
return error;
}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 46aa450..8cc0a72 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -428,7 +428,7 @@
FileSpec dependent_file_spec (dependent_files.GetFileSpecPointerAtIndex(i));
FileSpec platform_dependent_file_spec;
if (m_platform_sp)
- m_platform_sp->GetFile (dependent_file_spec, platform_dependent_file_spec);
+ m_platform_sp->GetFile (dependent_file_spec, NULL, platform_dependent_file_spec);
else
platform_dependent_file_spec = dependent_file_spec;
diff --git a/lldb/source/Utility/StringExtractorGDBRemote.cpp b/lldb/source/Utility/StringExtractorGDBRemote.cpp
index fc64b27..372eaee 100644
--- a/lldb/source/Utility/StringExtractorGDBRemote.cpp
+++ b/lldb/source/Utility/StringExtractorGDBRemote.cpp
@@ -59,6 +59,11 @@
const char *packet_cstr = m_packet.c_str();
switch (m_packet[0])
{
+ case '\x03':
+ if (m_packet.size() == 1)
+ return eServerPacketType_interrupt;
+ break;
+
case '-':
if (m_packet.size() == 1)
return eServerPacketType_nack;
diff --git a/lldb/source/Utility/StringExtractorGDBRemote.h b/lldb/source/Utility/StringExtractorGDBRemote.h
index e8c4177..8c65e0c 100644
--- a/lldb/source/Utility/StringExtractorGDBRemote.h
+++ b/lldb/source/Utility/StringExtractorGDBRemote.h
@@ -45,6 +45,7 @@
eServerPacketType_ack,
eServerPacketType_invalid,
eServerPacketType_unimplemented,
+ eServerPacketType_interrupt, // CTRL+c packet or "\x03"
eServerPacketType_qHostInfo
};