diff options
author | Greg Clayton <gclayton@apple.com> | 2011-04-12 05:54:46 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2011-04-12 05:54:46 +0000 |
commit | 8b82f087a0499319640f5d06498f965fa0214c72 (patch) | |
tree | 561c493dbe3e1a176d4c1b4ddd0c0afb396d3bea /lldb/source/Plugins/Process | |
parent | f52718899fa93f19403336355bca8117321ee834 (diff) | |
download | bcm5719-llvm-8b82f087a0499319640f5d06498f965fa0214c72.tar.gz bcm5719-llvm-8b82f087a0499319640f5d06498f965fa0214c72.zip |
Moved the execution context that was in the Debugger into
the CommandInterpreter where it was always being used.
Make sure that Modules can track their object file offsets correctly to
allow opening of sub object files (like the "__commpage" on darwin).
Modified the Platforms to be able to launch processes. The first part of this
move is the platform soon will become the entity that launches your program
and when it does, it uses a new ProcessLaunchInfo class which encapsulates
all process launching settings. This simplifies the internal APIs needed for
launching. I want to slowly phase out process launching from the process
classes, so for now we can still launch just as we used to, but eventually
the platform is the object that should do the launching.
Modified the Host::LaunchProcess in the MacOSX Host.mm to correctly be able
to launch processes with all of the new eLaunchFlag settings. Modified any
code that was manually launching processes to use the Host::LaunchProcess
functions.
Fixed an issue where lldb_private::Args had implicitly defined copy
constructors that could do the wrong thing. This has now been fixed by adding
an appropriate copy constructor and assignment operator.
Make sure we don't add empty ModuleSP entries to a module list.
Fixed the commpage module creation on MacOSX, but we still need to train
the MacOSX dynamic loader to not get rid of it when it doesn't have an entry
in the all image infos.
Abstracted many more calls from in ProcessGDBRemote down into the
GDBRemoteCommunicationClient subclass to make the classes cleaner and more
efficient.
Fixed the default iOS ARM register context to be correct and also added support
for targets that don't support the qThreadStopInfo packet by selecting the
current thread (only if needed) and then sending a stop reply packet.
Debugserver can now start up with a --unix-socket (-u for short) and can
then bind to port zero and send the port it bound to to a listening process
on the other end. This allows the GDB remote platform to spawn new GDB server
instances (debugserver) to allow platform debugging.
llvm-svn: 129351
Diffstat (limited to 'lldb/source/Plugins/Process')
10 files changed, 1034 insertions, 417 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 3b8d6056063..93e4166af2c 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -17,25 +17,33 @@ // Other libraries and framework includes #include "lldb/Core/Log.h" #include "lldb/Core/StreamString.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/Host.h" #include "lldb/Host/TimeValue.h" +#include "lldb/Target/Process.h" // Project includes #include "ProcessGDBRemoteLog.h" +#define DEBUGSERVER_BASENAME "debugserver" + using namespace lldb; using namespace lldb_private; //---------------------------------------------------------------------- // GDBRemoteCommunication constructor //---------------------------------------------------------------------- -GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char *listener_name) : +GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, + const char *listener_name, + bool is_platform) : Communication(comm_name), m_packet_timeout (60), m_rx_packet_listener (listener_name), m_sequence_mutex (Mutex::eMutexTypeRecursive), m_public_is_running (false), m_private_is_running (false), - m_send_acks (true) + m_send_acks (true), + m_is_platform (is_platform) { m_rx_packet_listener.StartListeningForEvents(this, Communication::eBroadcastBitPacketAvailable | @@ -328,3 +336,131 @@ GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, } } +Error +GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url, + const char *unix_socket_name, // For handshaking + lldb_private::ProcessLaunchInfo &launch_info) +{ + Error error; + // If we locate debugserver, keep that located version around + static FileSpec g_debugserver_file_spec; + + // This function will fill in the launch information for the debugserver + // instance that gets launched. + launch_info.Clear(); + + char debugserver_path[PATH_MAX]; + FileSpec &debugserver_file_spec = launch_info.GetExecutableFile(); + + // Always check to see if we have an environment override for the path + // to the debugserver to use and use it if we do. + const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH"); + if (env_debugserver_path) + debugserver_file_spec.SetFile (env_debugserver_path, false); + else + debugserver_file_spec = g_debugserver_file_spec; + bool debugserver_exists = debugserver_file_spec.Exists(); + if (!debugserver_exists) + { + // The debugserver binary is in the LLDB.framework/Resources + // directory. + if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec)) + { + debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME); + debugserver_exists = debugserver_file_spec.Exists(); + if (debugserver_exists) + { + g_debugserver_file_spec = debugserver_file_spec; + } + else + { + g_debugserver_file_spec.Clear(); + debugserver_file_spec.Clear(); + } + } + } + + if (debugserver_exists) + { + debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path)); + + Args &debugserver_args = launch_info.GetArguments(); + debugserver_args.Clear(); + char arg_cstr[PATH_MAX]; + + // Start args with "debugserver /file/path -r --" + debugserver_args.AppendArgument(debugserver_path); + debugserver_args.AppendArgument(debugserver_url); + // use native registers, not the GDB registers + debugserver_args.AppendArgument("--native-regs"); + // make debugserver run in its own session so signals generated by + // special terminal key sequences (^C) don't affect debugserver + debugserver_args.AppendArgument("--setsid"); + + if (unix_socket_name && unix_socket_name[0]) + { + debugserver_args.AppendArgument("--unix-socket"); + debugserver_args.AppendArgument(unix_socket_name); + } + + const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE"); + if (env_debugserver_log_file) + { + ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file); + debugserver_args.AppendArgument(arg_cstr); + } + + const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS"); + if (env_debugserver_log_flags) + { + ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags); + debugserver_args.AppendArgument(arg_cstr); + } + // debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt"); + // debugserver_args.AppendArgument("--log-flags=0x802e0e"); + + // We currently send down all arguments, attach pids, or attach + // process names in dedicated GDB server packets, so we don't need + // to pass them as arguments. This is currently because of all the + // things we need to setup prior to launching: the environment, + // current working dir, file actions, etc. +#if 0 + // Now append the program arguments + if (inferior_argv) + { + // Terminate the debugserver args so we can now append the inferior args + debugserver_args.AppendArgument("--"); + + for (int i = 0; inferior_argv[i] != NULL; ++i) + debugserver_args.AppendArgument (inferior_argv[i]); + } + else if (attach_pid != LLDB_INVALID_PROCESS_ID) + { + ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid); + debugserver_args.AppendArgument (arg_cstr); + } + else if (attach_name && attach_name[0]) + { + if (wait_for_launch) + debugserver_args.AppendArgument ("--waitfor"); + else + debugserver_args.AppendArgument ("--attach"); + debugserver_args.AppendArgument (attach_name); + } +#endif + + // Close STDIN, STDOUT and STDERR. We might need to redirect them + // to "/dev/null" if we run into any problems. +// launch_info.AppendCloseFileAction (STDIN_FILENO); +// launch_info.AppendCloseFileAction (STDOUT_FILENO); +// launch_info.AppendCloseFileAction (STDERR_FILENO); + + error = Host::LaunchProcess(launch_info); + } + else + { + error.SetErrorStringWithFormat ("Unable to locate " DEBUGSERVER_BASENAME ".\n"); + } + return error; +} + diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index f53d036a518..77e3e1a5d7c 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -37,7 +37,9 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - GDBRemoteCommunication(const char *comm_name, const char *listener_name); + GDBRemoteCommunication(const char *comm_name, + const char *listener_name, + bool is_platform); virtual ~GDBRemoteCommunication(); @@ -119,6 +121,15 @@ public: return old_packet_timeout; } + //------------------------------------------------------------------ + // Start a debugserver instance on the current host using the + // supplied connection URL. + //------------------------------------------------------------------ + lldb_private::Error + StartDebugserverProcess (const char *connect_url, + const char *unix_socket_name, + lldb_private::ProcessLaunchInfo &launch_info); + protected: typedef std::list<std::string> packet_collection; @@ -142,10 +153,13 @@ protected: lldb_private::Predicate<bool> m_public_is_running; lldb_private::Predicate<bool> m_private_is_running; bool m_send_acks; - + bool m_is_platform; // Set to true if this class represents a platform, + // false if this class represents a debug session for + // a single process + private: //------------------------------------------------------------------ // For GDBRemoteCommunication only diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 2cebb10c0fb..d4f6592f5bd 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -34,8 +34,8 @@ using namespace lldb_private; //---------------------------------------------------------------------- // GDBRemoteCommunicationClient constructor //---------------------------------------------------------------------- -GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : - GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"), +GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : + GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform), m_supports_not_sending_acks (eLazyBoolCalculate), m_supports_thread_suffix (eLazyBoolCalculate), m_supports_vCont_all (eLazyBoolCalculate), @@ -49,6 +49,14 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : m_supports_qfProcessInfo (true), m_supports_qUserName (true), m_supports_qGroupName (true), + m_supports_qThreadStopInfo (true), + m_supports_z0 (true), + m_supports_z1 (true), + m_supports_z2 (true), + m_supports_z3 (true), + m_supports_z4 (true), + m_curr_tid (LLDB_INVALID_THREAD_ID), + m_curr_tid_run (LLDB_INVALID_THREAD_ID), m_async_mutex (Mutex::eMutexTypeRecursive), m_async_packet_predicate (false), m_async_packet (), @@ -126,6 +134,12 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings() m_supports_qfProcessInfo = true; m_supports_qUserName = true; m_supports_qGroupName = true; + m_supports_qThreadStopInfo = true; + m_supports_z0 = true; + m_supports_z1 = true; + m_supports_z2 = true; + m_supports_z3 = true; + m_supports_z4 = true; m_host_arch.Clear(); } @@ -1119,7 +1133,7 @@ GDBRemoteCommunicationClient::SetDisableASLR (bool enable) } bool -GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInfo &process_info) +GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) { if (response.IsNormalResponse()) { @@ -1139,7 +1153,7 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot } else if (name.compare("uid") == 0) { - process_info.SetRealUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); + process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); } else if (name.compare("euid") == 0) { @@ -1147,7 +1161,7 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot } else if (name.compare("gid") == 0) { - process_info.SetRealGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); + process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); } else if (name.compare("egid") == 0) { @@ -1180,7 +1194,7 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot } bool -GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info) +GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) { process_info.Clear(); @@ -1205,8 +1219,8 @@ GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc } uint32_t -GDBRemoteCommunicationClient::FindProcesses (const ProcessInfoMatch &match_info, - ProcessInfoList &process_infos) +GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { process_infos.Clear(); @@ -1261,10 +1275,10 @@ GDBRemoteCommunicationClient::FindProcesses (const ProcessInfoMatch &match_info, packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID()); if (match_info.GetProcessInfo().ParentProcessIDIsValid()) packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID()); - if (match_info.GetProcessInfo().RealUserIDIsValid()) - packet.Printf("uid:%u;",match_info.GetProcessInfo().GetRealUserID()); - if (match_info.GetProcessInfo().RealGroupIDIsValid()) - packet.Printf("gid:%u;",match_info.GetProcessInfo().GetRealGroupID()); + if (match_info.GetProcessInfo().UserIDIsValid()) + packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID()); + if (match_info.GetProcessInfo().GroupIDIsValid()) + packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID()); if (match_info.GetProcessInfo().EffectiveUserIDIsValid()) packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID()); if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) @@ -1291,7 +1305,7 @@ GDBRemoteCommunicationClient::FindProcesses (const ProcessInfoMatch &match_info, do { - ProcessInfo process_info; + ProcessInstanceInfo process_info; if (!DecodeProcessInfoResponse (response, process_info)) break; process_infos.Append(process_info); @@ -1447,3 +1461,154 @@ GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t } return false; } + +uint16_t +GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort () +{ + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false)) + { + std::string name; + std::string value; + uint16_t port = 0; + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + while (response.GetNameColonValue(name, value)) + { + if (name.size() == 4 && name.compare("port") == 0) + port = Args::StringToUInt32(value.c_str(), 0, 0); + if (name.size() == 3 && name.compare("pid") == 0) + pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0); + } + return port; + } + return 0; +} + +bool +GDBRemoteCommunicationClient::SetCurrentThread (int tid) +{ + if (m_curr_tid == tid) + return true; + + char packet[32]; + int packet_len; + if (tid <= 0) + packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid); + else + packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid); + assert (packet_len + 1 < sizeof(packet)); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) + { + if (response.IsOKResponse()) + { + m_curr_tid = tid; + return true; + } + } + return false; +} + +bool +GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid) +{ + if (m_curr_tid_run == tid) + return true; + + char packet[32]; + int packet_len; + if (tid <= 0) + packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid); + else + packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid); + + assert (packet_len + 1 < sizeof(packet)); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) + { + if (response.IsOKResponse()) + { + m_curr_tid_run = tid; + return true; + } + } + return false; +} + +bool +GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response) +{ + if (SendPacketAndWaitForResponse("?", 1, response, false)) + return response.IsNormalResponse(); + return false; +} + +bool +GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response) +{ + if (m_supports_qThreadStopInfo) + { + char packet[256]; + int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid); + assert (packet_len < sizeof(packet)); + if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) + { + if (response.IsUnsupportedResponse()) + m_supports_qThreadStopInfo = false; + else if (response.IsNormalResponse()) + return true; + else + return false; + } + } + if (SetCurrentThread (tid)) + return GetStopReply (response); + return false; +} + + +uint8_t +GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length) +{ + switch (type) + { + case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break; + case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break; + case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break; + case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break; + case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break; + default: return UINT8_MAX; + } + + char packet[64]; + const int packet_len = ::snprintf (packet, + sizeof(packet), + "%c%i,%llx,%x", + insert ? 'Z' : 'z', + type, + addr, + length); + + assert (packet_len + 1 < sizeof(packet)); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse(packet, packet_len, response, true)) + { + if (response.IsOKResponse()) + return 0; + if (response.IsUnsupportedResponse()) + { + switch (type) + { + case eBreakpointSoftware: m_supports_z0 = false; break; + case eBreakpointHardware: m_supports_z1 = false; break; + case eWatchpointWrite: m_supports_z2 = false; break; + case eWatchpointRead: m_supports_z3 = false; break; + case eWatchpointReadWrite: m_supports_z4 = false; break; + default: break; + } + } + else if (response.IsErrorResponse()) + return response.GetError(); + } + return UINT8_MAX; +} diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index ae1674a4d1f..5c24d642470 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -18,13 +18,22 @@ #include "GDBRemoteCommunication.h" +typedef enum +{ + eBreakpointSoftware = 0, + eBreakpointHardware, + eWatchpointWrite, + eWatchpointRead, + eWatchpointReadWrite +} GDBStoppointType; + class GDBRemoteCommunicationClient : public GDBRemoteCommunication { public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - GDBRemoteCommunicationClient(); + GDBRemoteCommunicationClient(bool is_platform); virtual ~GDBRemoteCommunicationClient(); @@ -74,6 +83,9 @@ public: bool GetLaunchSuccess (std::string &error_str); + uint16_t + LaunchGDBserverAndGetPort (); + //------------------------------------------------------------------ /// Sends a GDB remote protocol 'A' packet that delivers program /// arguments to the remote server. @@ -214,11 +226,11 @@ public: bool GetProcessInfo (lldb::pid_t pid, - lldb_private::ProcessInfo &process_info); + lldb_private::ProcessInstanceInfo &process_info); uint32_t - FindProcesses (const lldb_private::ProcessInfoMatch &process_match_info, - lldb_private::ProcessInfoList &process_infos); + FindProcesses (const lldb_private::ProcessInstanceInfoMatch &process_match_info, + lldb_private::ProcessInstanceInfoList &process_infos); bool GetUserName (uint32_t uid, std::string &name); @@ -246,6 +258,33 @@ public: return old_packet_timeout; } + bool + GetStopReply (StringExtractorGDBRemote &response); + + bool + GetThreadStopInfo (uint32_t tid, + StringExtractorGDBRemote &response); + + bool + SupportsGDBStoppointPacket (GDBStoppointType type) + { + switch (type) + { + case eBreakpointSoftware: return m_supports_z0; + case eBreakpointHardware: return m_supports_z1; + case eWatchpointWrite: return m_supports_z2; + case eWatchpointRead: return m_supports_z3; + case eWatchpointReadWrite: return m_supports_z4; + default: break; + } + return false; + } + uint8_t + SendGDBStoppointTypePacket (GDBStoppointType type, // Type of breakpoint or watchpoint + bool insert, // Insert or remove? + lldb::addr_t addr, // Address of breakpoint or watchpoint + uint32_t length); // Byte Size of breakpoint or watchpoint + void TestPacketSpeed (const uint32_t num_packets); @@ -257,6 +296,13 @@ public: bool SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size); + + bool + SetCurrentThread (int tid); + + bool + SetCurrentThreadForRun (int tid); + protected: //------------------------------------------------------------------ @@ -271,10 +317,21 @@ protected: lldb_private::LazyBool m_supports_vCont_s; lldb_private::LazyBool m_supports_vCont_S; lldb_private::LazyBool m_qHostInfo_is_valid; - bool m_supports_qProcessInfoPID; - bool m_supports_qfProcessInfo; - bool m_supports_qUserName; - bool m_supports_qGroupName; + bool + m_supports_qProcessInfoPID:1, + m_supports_qfProcessInfo:1, + m_supports_qUserName:1, + m_supports_qGroupName:1, + m_supports_qThreadStopInfo:1, + m_supports_z0:1, + m_supports_z1:1, + m_supports_z2:1, + m_supports_z3:1, + m_supports_z4:1; + + lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all other operations + lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for continue, step, etc + // If we need to send a packet while the target is running, the m_async_XXX // member variables take care of making this happen. @@ -294,7 +351,7 @@ protected: bool DecodeProcessInfoResponse (StringExtractorGDBRemote &response, - lldb_private::ProcessInfo &process_info); + lldb_private::ProcessInstanceInfo &process_info); private: //------------------------------------------------------------------ // For GDBRemoteCommunicationClient only diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index c2431380fd9..9379077335d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -21,6 +21,7 @@ #include "lldb/Core/StreamString.h" #include "lldb/Host/Host.h" #include "lldb/Host/TimeValue.h" +#include "lldb/Target/Process.h" // Project includes #include "Utility/StringExtractorGDBRemote.h" @@ -33,9 +34,15 @@ using namespace lldb_private; //---------------------------------------------------------------------- // GDBRemoteCommunicationServer constructor //---------------------------------------------------------------------- -GDBRemoteCommunicationServer::GDBRemoteCommunicationServer() : - GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet"), - m_async_thread (LLDB_INVALID_HOST_THREAD) +GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) : + GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform), + m_async_thread (LLDB_INVALID_HOST_THREAD), + m_process_launch_info (), + m_process_launch_error (), + m_proc_infos (), + m_proc_infos_index (0), + m_lo_port_num (0), + m_hi_port_num (0) { } @@ -82,45 +89,76 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType (); switch (packet_type) { - case StringExtractorGDBRemote::eServerPacketType_nack: - case StringExtractorGDBRemote::eServerPacketType_ack: - break; - - case StringExtractorGDBRemote::eServerPacketType_invalid: - error.SetErrorString("invalid packet"); - quit = true; - break; - - case StringExtractorGDBRemote::eServerPacketType_interrupt: - error.SetErrorString("interrupt received"); - interrupt = true; - break; - - case StringExtractorGDBRemote::eServerPacketType_unimplemented: - return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0; - - case StringExtractorGDBRemote::eServerPacketType_qHostInfo: - return Handle_qHostInfo (packet); - - case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID: - return Handle_qProcessInfoPID (packet); - - case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo: - return Handle_qfProcessInfo (packet); - - case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo: - return Handle_qsProcessInfo (packet); - - case StringExtractorGDBRemote::eServerPacketType_qUserName: - return Handle_qUserName (packet); - - case StringExtractorGDBRemote::eServerPacketType_qGroupName: - return Handle_qGroupName (packet); - - case StringExtractorGDBRemote::eServerPacketType_qSpeedTest: - return Handle_qSpeedTest (packet); - case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode: - return Handle_QStartNoAckMode (packet); + case StringExtractorGDBRemote::eServerPacketType_nack: + case StringExtractorGDBRemote::eServerPacketType_ack: + break; + + case StringExtractorGDBRemote::eServerPacketType_invalid: + error.SetErrorString("invalid packet"); + quit = true; + break; + + case StringExtractorGDBRemote::eServerPacketType_interrupt: + error.SetErrorString("interrupt received"); + interrupt = true; + break; + + case StringExtractorGDBRemote::eServerPacketType_unimplemented: + return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0; + + case StringExtractorGDBRemote::eServerPacketType_A: + return Handle_A (packet); + + case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo: + return Handle_qfProcessInfo (packet); + + case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo: + return Handle_qsProcessInfo (packet); + + case StringExtractorGDBRemote::eServerPacketType_qC: + return Handle_qC (packet); + + case StringExtractorGDBRemote::eServerPacketType_qHostInfo: + return Handle_qHostInfo (packet); + + case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer: + return Handle_qLaunchGDBServer (packet); + + case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess: + return Handle_qLaunchSuccess (packet); + + case StringExtractorGDBRemote::eServerPacketType_qGroupName: + return Handle_qGroupName (packet); + + case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID: + return Handle_qProcessInfoPID (packet); + + case StringExtractorGDBRemote::eServerPacketType_qSpeedTest: + return Handle_qSpeedTest (packet); + + case StringExtractorGDBRemote::eServerPacketType_qUserName: + return Handle_qUserName (packet); + + case StringExtractorGDBRemote::eServerPacketType_QEnvironment: + return Handle_QEnvironment (packet); + + case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR: + return Handle_QSetDisableASLR (packet); + + case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN: + return Handle_QSetSTDIN (packet); + + case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT: + return Handle_QSetSTDOUT (packet); + + case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR: + return Handle_QSetSTDERR (packet); + + case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir: + return Handle_QSetWorkingDir (packet); + + case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode: + return Handle_QStartNoAckMode (packet); } return true; } @@ -236,13 +274,13 @@ GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet } static void -CreateProcessInfoResponse (const ProcessInfo &proc_info, StreamString &response) +CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response) { response.Printf ("pid:%i;ppid:%i;uid:%i;gid:%i;euid:%i;egid:%i;", proc_info.GetProcessID(), proc_info.GetParentProcessID(), - proc_info.GetRealUserID(), - proc_info.GetRealGroupID(), + proc_info.GetUserID(), + proc_info.GetGroupID(), proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID()); response.PutCString ("name:"); @@ -262,11 +300,11 @@ bool GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet) { // Packet format: "qProcessInfoPID:%i" where %i is the pid - packet.SetFilePos(strlen ("qProcessInfoPID:")); + packet.SetFilePos(::strlen ("qProcessInfoPID:")); lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID); if (pid != LLDB_INVALID_PROCESS_ID) { - ProcessInfo proc_info; + ProcessInstanceInfo proc_info; if (Host::GetProcessInfo(pid, proc_info)) { StreamString response; @@ -283,8 +321,8 @@ GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &pa m_proc_infos_index = 0; m_proc_infos.Clear(); - ProcessInfoMatch match_info; - packet.SetFilePos(strlen ("qfProcessInfo")); + ProcessInstanceInfoMatch match_info; + packet.SetFilePos(::strlen ("qfProcessInfo")); if (packet.GetChar() == ':') { @@ -337,11 +375,11 @@ GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &pa } else if (key.compare("uid") == 0) { - match_info.GetProcessInfo().SetRealUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); + match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); } else if (key.compare("gid") == 0) { - match_info.GetProcessInfo().SetRealGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); + match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); } else if (key.compare("euid") == 0) { @@ -395,7 +433,7 @@ bool GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet) { // Packet format: "qUserName:%i" where %i is the uid - packet.SetFilePos(strlen ("qUserName:")); + packet.SetFilePos(::strlen ("qUserName:")); uint32_t uid = packet.GetU32 (UINT32_MAX); if (uid != UINT32_MAX) { @@ -415,7 +453,7 @@ bool GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet) { // Packet format: "qGroupName:%i" where %i is the gid - packet.SetFilePos(strlen ("qGroupName:")); + packet.SetFilePos(::strlen ("qGroupName:")); uint32_t gid = packet.GetU32 (UINT32_MAX); if (gid != UINT32_MAX) { @@ -433,7 +471,7 @@ GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packe bool GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet) { - packet.SetFilePos(strlen ("qSpeedTest:")); + packet.SetFilePos(::strlen ("qSpeedTest:")); std::string key; std::string value; @@ -466,6 +504,327 @@ GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packe } return SendErrorResponse (7); } + + +static void * +AcceptPortFromInferior (void *arg) +{ + const char *connect_url = (const char *)arg; + ConnectionFileDescriptor file_conn; + Error error; + if (file_conn.Connect (connect_url, &error) == eConnectionStatusSuccess) + { + char pid_str[256]; + ::memset (pid_str, 0, sizeof(pid_str)); + ConnectionStatus status; + const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), status, NULL); + if (pid_str_len > 0) + { + int pid = atoi (pid_str); + return (void *)(intptr_t)pid; + } + } + return NULL; +} +// +//static bool +//WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) +//{ +// const int time_delta_usecs = 100000; +// const int num_retries = timeout_in_seconds/time_delta_usecs; +// for (int i=0; i<num_retries; i++) +// { +// struct proc_bsdinfo bsd_info; +// int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO, +// (uint64_t) 0, +// &bsd_info, +// PROC_PIDTBSDINFO_SIZE); +// +// switch (error) +// { +// case EINVAL: +// case ENOTSUP: +// case ESRCH: +// case EPERM: +// return false; +// +// default: +// break; +// +// case 0: +// if (bsd_info.pbi_status == SSTOP) +// return true; +// } +// ::usleep (time_delta_usecs); +// } +// return false; +//} + +bool +GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet) +{ + // The 'A' packet is the most over designed packet ever here with + // redundant argument indexes, redundant argument lengths and needed hex + // encoded argument string values. Really all that is needed is a comma + // separated hex encoded argument value list, but we will stay true to the + // documented version of the 'A' packet here... + + packet.SetFilePos(1); // Skip the 'A' + bool success = true; + while (success && packet.GetBytesLeft() > 0) + { + // Decode the decimal argument string length. This length is the + // number of hex nibbles in the argument string value. + const uint32_t arg_len = packet.GetU32(UINT32_MAX); + if (arg_len == UINT32_MAX) + success = false; + else + { + // Make sure the argument hex string length is followed by a comma + if (packet.GetChar() != ',') + success = false; + else + { + // Decode the argument index. We ignore this really becuase + // who would really send down the arguments in a random order??? + const uint32_t arg_idx = packet.GetU32(UINT32_MAX); + if (arg_idx == UINT32_MAX) + success = false; + else + { + // Make sure the argument index is followed by a comma + if (packet.GetChar() != ',') + success = false; + else + { + // Decode the argument string value from hex bytes + // back into a UTF8 string and make sure the length + // matches the one supplied in the packet + std::string arg; + if (packet.GetHexByteString(arg) != (arg_len / 2)) + success = false; + else + { + // If there are any bytes lft + if (packet.GetBytesLeft()) + { + if (packet.GetChar() != ',') + success = false; + } + + if (success) + { + if (arg_idx == 0) + m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false); + m_process_launch_info.GetArguments().AppendArgument(arg.c_str()); + } + } + } + } + } + } + } + + if (success) + { + m_process_launch_info.GetFlags().Set (eLaunchFlagDebug); + m_process_launch_error = Host::LaunchProcess (m_process_launch_info); + if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) + { + return SendOKResponse (); + } + } + return SendErrorResponse (8); +} + +bool +GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet) +{ + lldb::pid_t pid = m_process_launch_info.GetProcessID(); + StreamString response; + response.Printf("QC%x", pid); + if (m_is_platform) + { + // If we launch a process and this GDB server is acting as a platform, + // then we need to clear the process launch state so we can start + // launching another process. In order to launch a process a bunch or + // packets need to be sent: environment packets, working directory, + // disable ASLR, and many more settings. When we launch a process we + // then need to know when to clear this information. Currently we are + // selecting the 'qC' packet as that packet which seems to make the most + // sense. + if (pid != LLDB_INVALID_PROCESS_ID) + { + m_process_launch_info.Clear(); + } + } + return SendPacket (response); +} + +bool +GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet) +{ + // Spawn a local debugserver as a platform so we can then attach or launch + // a process... + + if (m_is_platform) + { + // Sleep and wait a bit for debugserver to start to listen... + ConnectionFileDescriptor file_conn; + char connect_url[PATH_MAX]; + Error error; + char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX"; + if (::mktemp (unix_socket_name) == NULL) + { + error.SetErrorString ("failed to make temporary path for a unix socket"); + } + else + { + ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name); + // Spawn a new thread to accept the port that gets bound after + // binding to port 0 (zero). + lldb::thread_t accept_thread = Host::ThreadCreate (unix_socket_name, + AcceptPortFromInferior, + connect_url, + &error); + + if (IS_VALID_LLDB_HOST_THREAD(accept_thread)) + { + // Spawn a debugserver and try to get + ProcessLaunchInfo debugserver_launch_info; + error = StartDebugserverProcess ("localhost:0", + unix_socket_name, + debugserver_launch_info); + + lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); + if (error.Success()) + { + bool success = false; + + thread_result_t accept_thread_result = NULL; + if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error)) + { + if (accept_thread_result) + { + uint16_t port = (intptr_t)accept_thread_result; + char response[256]; + const int response_len = ::snprintf (response, sizeof(response), "pid:%u;port:%u;", debugserver_pid, port); + assert (response_len < sizeof(response)); + //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); + success = SendPacket (response, response_len) > 0; + } + } + ::unlink (unix_socket_name); + + if (!success) + { + if (debugserver_pid != LLDB_INVALID_PROCESS_ID) + ::kill (debugserver_pid, SIGINT); + } + return success; + } + } + } + } + return SendErrorResponse (13); +} + +bool +GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet) +{ + if (m_process_launch_error.Success()) + return SendOKResponse(); + StreamString response; + response.PutChar('E'); + response.PutCString(m_process_launch_error.AsCString("<unknown error>")); + return SendPacket (response); +} + +bool +GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &packet) +{ + packet.SetFilePos(::strlen ("QEnvironment:")); + const uint32_t bytes_left = packet.GetBytesLeft(); + if (bytes_left > 0) + { + m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek()); + return SendOKResponse (); + } + return SendErrorResponse (9); +} + +bool +GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet) +{ + packet.SetFilePos(::strlen ("QSetDisableASLR:")); + if (packet.GetU32(0)) + m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR); + else + m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); + return SendOKResponse (); +} + +bool +GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet) +{ + packet.SetFilePos(::strlen ("QSetWorkingDir:")); + std::string path; + packet.GetHexByteString(path); + m_process_launch_info.SwapWorkingDirectory (path); + return SendOKResponse (); +} + +bool +GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet) +{ + packet.SetFilePos(::strlen ("QSetSTDIN:")); + ProcessLaunchInfo::FileAction file_action; + std::string path; + packet.GetHexByteString(path); + const bool read = false; + const bool write = true; + if (file_action.Open(STDIN_FILENO, path.c_str(), read, write)) + { + m_process_launch_info.AppendFileAction(file_action); + return SendOKResponse (); + } + return SendErrorResponse (10); +} + +bool +GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet) +{ + packet.SetFilePos(::strlen ("QSetSTDOUT:")); + ProcessLaunchInfo::FileAction file_action; + std::string path; + packet.GetHexByteString(path); + const bool read = true; + const bool write = false; + if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write)) + { + m_process_launch_info.AppendFileAction(file_action); + return SendOKResponse (); + } + return SendErrorResponse (11); +} + +bool +GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet) +{ + packet.SetFilePos(::strlen ("QSetSTDERR:")); + ProcessLaunchInfo::FileAction file_action; + std::string path; + packet.GetHexByteString(path); + const bool read = true; + const bool write = true; + if (file_action.Open(STDERR_FILENO, path.c_str(), read, write)) + { + m_process_launch_info.AppendFileAction(file_action); + return SendOKResponse (); + } + return SendErrorResponse (12); +} + bool GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet) { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 02440a2db96..1fddaeb5fea 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -31,7 +31,7 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - GDBRemoteCommunicationServer(); + GDBRemoteCommunicationServer(bool is_platform); virtual ~GDBRemoteCommunicationServer(); @@ -53,10 +53,26 @@ public: bool HandshakeWithClient (lldb_private::Error *error_ptr); + // Set both ports to zero to let the platform automatically bind to + // a port chosen by the OS. + void + SetPortRange (uint16_t lo_port_num, uint16_t hi_port_num) + { + m_lo_port_num = lo_port_num; + m_hi_port_num = hi_port_num; + } + protected: + //typedef std::map<uint16_t, lldb::pid_t> PortToPIDMap; + lldb::thread_t m_async_thread; - lldb_private::ProcessInfoList m_proc_infos; + lldb_private::ProcessLaunchInfo m_process_launch_info; + lldb_private::Error m_process_launch_error; + lldb_private::ProcessInstanceInfoList m_proc_infos; uint32_t m_proc_infos_index; + uint16_t m_lo_port_num; + uint16_t m_hi_port_num; + //PortToPIDMap m_port_to_pid_map; size_t SendUnimplementedResponse (const char *packet); @@ -68,9 +84,18 @@ protected: SendOKResponse (); bool + Handle_A (StringExtractorGDBRemote &packet); + + bool + Handle_qLaunchSuccess (StringExtractorGDBRemote &packet); + + bool Handle_qHostInfo (StringExtractorGDBRemote &packet); bool + Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet); + + bool Handle_qProcessInfoPID (StringExtractorGDBRemote &packet); bool @@ -79,6 +104,9 @@ protected: bool Handle_qsProcessInfo (StringExtractorGDBRemote &packet); + bool + Handle_qC (StringExtractorGDBRemote &packet); + bool Handle_qUserName (StringExtractorGDBRemote &packet); @@ -89,8 +117,26 @@ protected: Handle_qSpeedTest (StringExtractorGDBRemote &packet); bool + Handle_QEnvironment (StringExtractorGDBRemote &packet); + + bool + Handle_QSetDisableASLR (StringExtractorGDBRemote &packet); + + bool + Handle_QSetWorkingDir (StringExtractorGDBRemote &packet); + + bool Handle_QStartNoAckMode (StringExtractorGDBRemote &packet); + bool + Handle_QSetSTDIN (StringExtractorGDBRemote &packet); + + bool + Handle_QSetSTDOUT (StringExtractorGDBRemote &packet); + + bool + Handle_QSetSTDERR (StringExtractorGDBRemote &packet); + private: //------------------------------------------------------------------ // For GDBRemoteCommunicationServer only diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 0a1f87279f8..841efa207db 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -220,7 +220,7 @@ GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data) if (gdb_comm.GetSequenceMutex (locker)) { const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); - if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) + if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID())) { char packet[64]; StringExtractorGDBRemote response; @@ -329,7 +329,7 @@ GDBRemoteRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, if (gdb_comm.GetSequenceMutex (locker)) { const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); - if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) + if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID())) { uint32_t offset, end_offset; StreamString packet; @@ -407,7 +407,7 @@ GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) { char packet[32]; const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); - if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) + if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID())) { int packet_len = 0; if (thread_suffix_supported) @@ -449,7 +449,7 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data if (gdb_comm.GetSequenceMutex (locker)) { const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); - if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) + if (thread_suffix_supported || GetGDBProcess().GetGDBRemote().SetCurrentThread(m_thread.GetID())) { if (gdb_comm.SendPacketAndWaitForResponse((const char *)data_sp->GetBytes(), data_sp->GetByteSize(), @@ -474,91 +474,102 @@ GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, ui void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters() { - static RegisterInfo - g_register_infos[] = - { - // NAME ALT SZ OFF ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB NATIVE - // ====== ======= == ==== ============= ============ =============== =============== ========= ===== =========== - { "r0", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 0 }}, - { "r1", NULL, 4, 4, eEncodingUint, eFormatHex, { gcc_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 1 }}, - { "r2", NULL, 4, 8, eEncodingUint, eFormatHex, { gcc_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 2 }}, - { "r3", NULL, 4, 12, eEncodingUint, eFormatHex, { gcc_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 3 }}, - { "r4", NULL, 4, 16, eEncodingUint, eFormatHex, { gcc_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 4 }}, - { "r5", NULL, 4, 20, eEncodingUint, eFormatHex, { gcc_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 5 }}, - { "r6", NULL, 4, 24, eEncodingUint, eFormatHex, { gcc_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 6 }}, - { "r7", NULL, 4, 28, eEncodingUint, eFormatHex, { gcc_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, 7 }}, - { "r8", NULL, 4, 32, eEncodingUint, eFormatHex, { gcc_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 8 }}, - { "r9", NULL, 4, 36, eEncodingUint, eFormatHex, { gcc_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 9 }}, - { "r10", NULL, 4, 40, eEncodingUint, eFormatHex, { gcc_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 10 }}, - { "r11", NULL, 4, 44, eEncodingUint, eFormatHex, { gcc_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 11 }}, - { "r12", NULL, 4, 48, eEncodingUint, eFormatHex, { gcc_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 12 }}, - { "sp", "r13", 4, 52, eEncodingUint, eFormatHex, { gcc_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, 13 }}, - { "lr", "r14", 4, 56, eEncodingUint, eFormatHex, { gcc_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, 14 }}, - { "pc", "r15", 4, 60, eEncodingUint, eFormatHex, { gcc_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, 15 }}, -// { NULL, NULL, 12, 64, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 16 }}, -// { NULL, NULL, 12, 76, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 17 }}, -// { NULL, NULL, 12, 88, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 18 }}, -// { NULL, NULL, 12, 100, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 19 }}, -// { NULL, NULL, 12, 112, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 20 }}, -// { NULL, NULL, 12, 124, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 21 }}, -// { NULL, NULL, 12, 136, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 22 }}, -// { NULL, NULL, 12, 148, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 23 }}, -// { NULL, NULL, 12, 160, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 24 }}, - { "cpsr", "psr", 4, 172, eEncodingUint, eFormatHex, { gcc_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 25 }}, - { "s0", NULL, 4, 176, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 26 }}, - { "s1", NULL, 4, 180, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 27 }}, - { "s2", NULL, 4, 184, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 28 }}, - { "s3", NULL, 4, 188, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 29 }}, - { "s4", NULL, 4, 192, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 30 }}, - { "s5", NULL, 4, 196, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 31 }}, - { "s6", NULL, 4, 200, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 32 }}, - { "s7", NULL, 4, 204, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 33 }}, - { "s8", NULL, 4, 208, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 34 }}, - { "s9", NULL, 4, 212, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 35 }}, - { "s10", NULL, 4, 216, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 36 }}, - { "s11", NULL, 4, 220, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 37 }}, - { "s12", NULL, 4, 224, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 38 }}, - { "s13", NULL, 4, 228, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 39 }}, - { "s14", NULL, 4, 232, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 40 }}, - { "s15", NULL, 4, 236, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 41 }}, - { "s16", NULL, 4, 240, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 42 }}, - { "s17", NULL, 4, 244, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 43 }}, - { "s18", NULL, 4, 248, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 44 }}, - { "s19", NULL, 4, 252, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 45 }}, - { "s20", NULL, 4, 256, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 46 }}, - { "s21", NULL, 4, 260, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 47 }}, - { "s22", NULL, 4, 264, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 48 }}, - { "s23", NULL, 4, 268, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 49 }}, - { "s24", NULL, 4, 272, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 50 }}, - { "s25", NULL, 4, 276, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 51 }}, - { "s26", NULL, 4, 280, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 52 }}, - { "s27", NULL, 4, 284, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 53 }}, - { "s28", NULL, 4, 288, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 54 }}, - { "s29", NULL, 4, 292, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 55 }}, - { "s30", NULL, 4, 296, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 56 }}, - { "s31", NULL, 4, 300, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 57 }}, - { "fpscr", NULL, 4, 304, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58 }}, - { "d16", NULL, 8, 308, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 59 }}, - { "d17", NULL, 8, 316, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 60 }}, - { "d18", NULL, 8, 324, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 61 }}, - { "d19", NULL, 8, 332, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 62 }}, - { "d20", NULL, 8, 340, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 63 }}, - { "d21", NULL, 8, 348, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 64 }}, - { "d22", NULL, 8, 356, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 65 }}, - { "d23", NULL, 8, 364, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 66 }}, - { "d24", NULL, 8, 372, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 67 }}, - { "d25", NULL, 8, 380, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 68 }}, - { "d26", NULL, 8, 388, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 69 }}, - { "d27", NULL, 8, 396, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 70 }}, - { "d28", NULL, 8, 404, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 71 }}, - { "d29", NULL, 8, 412, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 72 }}, - { "d30", NULL, 8, 420, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 73 }}, - { "d31", NULL, 8, 428, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 74 }}, + static RegisterInfo g_register_infos[] = { +// NAME ALT SZ OFF ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB +// ====== ====== === === ============= ============ =================== =================== ====================== === ==== + { "r0", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r0, dwarf_r0, LLDB_INVALID_REGNUM, 0, 0 }}, + { "r1", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r1, dwarf_r1, LLDB_INVALID_REGNUM, 1, 1 }}, + { "r2", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r2, dwarf_r2, LLDB_INVALID_REGNUM, 2, 2 }}, + { "r3", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r3, dwarf_r3, LLDB_INVALID_REGNUM, 3, 3 }}, + { "r4", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }}, + { "r5", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }}, + { "r6", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }}, + { "r7", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }}, + { "r8", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }}, + { "r9", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }}, + { "r10", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }}, + { "r11", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }}, + { "r12", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }}, + { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { gcc_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }}, + { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { gcc_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }}, + { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { gcc_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }}, + { "f0", NULL, 12, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }}, + { "f1", NULL, 12, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }}, + { "f2", NULL, 12, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }}, + { "f3", NULL, 12, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }}, + { "f4", NULL, 12, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }}, + { "f5", NULL, 12, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }}, + { "f6", NULL, 12, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }}, + { "f7", NULL, 12, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }}, + { "fps", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }}, + { "cpsr", "psr", 4, 0, eEncodingUint, eFormatHex, { gcc_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }}, + { "s0", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }}, + { "s1", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }}, + { "s2", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }}, + { "s3", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }}, + { "s4", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }}, + { "s5", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }}, + { "s6", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }}, + { "s7", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }}, + { "s8", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }}, + { "s9", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }}, + { "s10", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }}, + { "s11", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }}, + { "s12", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }}, + { "s13", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }}, + { "s14", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }}, + { "s15", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }}, + { "s16", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }}, + { "s17", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }}, + { "s18", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }}, + { "s19", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }}, + { "s20", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }}, + { "s21", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }}, + { "s22", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }}, + { "s23", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }}, + { "s24", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }}, + { "s25", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }}, + { "s26", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }}, + { "s27", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }}, + { "s28", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }}, + { "s29", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }}, + { "s30", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }}, + { "s31", NULL, 4, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }}, + { "fpscr",NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }}, + { "d16", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }}, + { "d17", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }}, + { "d18", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }}, + { "d19", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }}, + { "d20", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }}, + { "d21", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }}, + { "d22", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }}, + { "d23", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }}, + { "d24", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }}, + { "d25", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }}, + { "d26", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }}, + { "d27", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }}, + { "d28", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }}, + { "d29", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }}, + { "d30", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }}, + { "d31", NULL, 8, 0, eEncodingIEEE754, eFormatHex, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }}, }; + static const uint32_t num_registers = sizeof (g_register_infos)/sizeof (RegisterInfo); static ConstString gpr_reg_set ("General Purpose Registers"); + static ConstString sfp_reg_set ("Software Floating Point Registers"); static ConstString vfp_reg_set ("Floating Point Registers"); - for (uint32_t i=0; i<num_registers; ++i) + uint32_t i; + // Calculate the offsets of the registers + if (g_register_infos[2].byte_offset == 0) + { + uint32_t byte_offset = 0; + for (i=0; i<num_registers; ++i) + { + g_register_infos[i].byte_offset = byte_offset; + byte_offset += g_register_infos[i].byte_size; + } + } + for (i=0; i<num_registers; ++i) { ConstString name; ConstString alt_name; @@ -566,8 +577,13 @@ GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters() name.SetCString(g_register_infos[i].name); if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0]) alt_name.SetCString(g_register_infos[i].alt_name); - - AddRegister (g_register_infos[i], name, alt_name, i < 26 ? gpr_reg_set : vfp_reg_set); + + if (i <= 15 || i == 25) + AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set); + else if (i <= 24) + AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set); + else + AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set); } } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index ec07fbee072..79f77e219d1 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -114,16 +114,13 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : Process (target, listener), m_flags (0), m_stdio_mutex (Mutex::eMutexTypeRecursive), - m_gdb_comm(), + m_gdb_comm(false), m_debugserver_pid (LLDB_INVALID_PROCESS_ID), m_debugserver_thread (LLDB_INVALID_HOST_THREAD), m_last_stop_packet (), m_register_info (), m_async_broadcaster ("lldb.process.gdb-remote.async-broadcaster"), m_async_thread (LLDB_INVALID_HOST_THREAD), - m_curr_tid (LLDB_INVALID_THREAD_ID), - m_curr_tid_run (LLDB_INVALID_THREAD_ID), - m_z0_supported (1), m_continue_c_tids (), m_continue_C_tids (), m_continue_s_tids (), @@ -430,7 +427,6 @@ ProcessGDBRemote::DoLaunch ObjectFile * object_file = module->GetObjectFile(); if (object_file) { - ArchSpec inferior_arch(module->GetArchitecture()); char host_port[128]; snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); char connect_url[128]; @@ -439,13 +435,7 @@ ProcessGDBRemote::DoLaunch // Make sure we aren't already connected? if (!m_gdb_comm.IsConnected()) { - error = StartDebugserverProcess (host_port, - NULL, - NULL, - LLDB_INVALID_PROCESS_ID, - NULL, - false, - inferior_arch); + error = StartDebugserverProcess (host_port); if (error.Fail()) return error; @@ -700,8 +690,6 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid) Error error; // Clear out and clean up from any current state Clear(); - const ArchSpec &arch_spec = GetTarget().GetArchitecture(); - if (attach_pid != LLDB_INVALID_PROCESS_ID) { // Make sure we aren't already connected? @@ -712,13 +700,7 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid) char connect_url[128]; snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port); - error = StartDebugserverProcess (host_port, // debugserver_url - NULL, // inferior_argv - NULL, // inferior_envp - LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver - NULL, // Don't send any attach by process name option to debugserver - false, // Don't send any attach wait_for_launch flag as an option to debugserver - arch_spec); + error = StartDebugserverProcess (host_port); if (error.Fail()) { @@ -778,21 +760,12 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait // Make sure we aren't already connected? if (!m_gdb_comm.IsConnected()) { - - const ArchSpec &arch_spec = GetTarget().GetArchitecture(); - char host_port[128]; snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); char connect_url[128]; snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port); - error = StartDebugserverProcess (host_port, // debugserver_url - NULL, // inferior_argv - NULL, // inferior_envp - LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver - NULL, // Don't send any attach by process name option to debugserver - false, // Don't send any attach wait_for_launch flag as an option to debugserver - arch_spec); + error = StartDebugserverProcess (host_port); if (error.Fail()) { const char *error_string = error.AsCString(); @@ -925,7 +898,7 @@ ProcessGDBRemote::DoResume () if (num_continue_c_tids == num_threads) { // All threads are resuming... - SetCurrentGDBRemoteThreadForRun (-1); + m_gdb_comm.SetCurrentThreadForRun (-1); continue_packet.PutChar ('c'); } else if (num_continue_c_tids == 1 && @@ -934,7 +907,7 @@ ProcessGDBRemote::DoResume () num_continue_S_tids == 0 ) { // Only one thread is continuing - SetCurrentGDBRemoteThreadForRun (m_continue_c_tids.front()); + m_gdb_comm.SetCurrentThreadForRun (m_continue_c_tids.front()); continue_packet.PutChar ('c'); } else @@ -960,7 +933,7 @@ ProcessGDBRemote::DoResume () if (!continue_packet_error) { // Add threads continuing with the same signo... - SetCurrentGDBRemoteThreadForRun (-1); + m_gdb_comm.SetCurrentThreadForRun (-1); continue_packet.Printf("C%2.2x", continue_signo); } } @@ -970,7 +943,7 @@ ProcessGDBRemote::DoResume () num_continue_S_tids == 0 ) { // Only one thread is continuing with signal - SetCurrentGDBRemoteThreadForRun (m_continue_C_tids.front().first); + m_gdb_comm.SetCurrentThreadForRun (m_continue_C_tids.front().first); continue_packet.Printf("C%2.2x", m_continue_C_tids.front().second); } else @@ -985,7 +958,7 @@ ProcessGDBRemote::DoResume () if (num_continue_s_tids == num_threads) { // All threads are resuming... - SetCurrentGDBRemoteThreadForRun (-1); + m_gdb_comm.SetCurrentThreadForRun (-1); continue_packet.PutChar ('s'); } else if (num_continue_c_tids == 0 && @@ -994,7 +967,7 @@ ProcessGDBRemote::DoResume () num_continue_S_tids == 0 ) { // Only one thread is stepping - SetCurrentGDBRemoteThreadForRun (m_continue_s_tids.front()); + m_gdb_comm.SetCurrentThreadForRun (m_continue_s_tids.front()); continue_packet.PutChar ('s'); } else @@ -1021,7 +994,7 @@ ProcessGDBRemote::DoResume () if (!continue_packet_error) { // Add threads stepping with the same signo... - SetCurrentGDBRemoteThreadForRun (-1); + m_gdb_comm.SetCurrentThreadForRun (-1); continue_packet.Printf("S%2.2x", step_signo); } } @@ -1031,7 +1004,7 @@ ProcessGDBRemote::DoResume () num_continue_S_tids == 1 ) { // Only one thread is stepping with signal - SetCurrentGDBRemoteThreadForRun (m_continue_S_tids.front().first); + m_gdb_comm.SetCurrentThreadForRun (m_continue_S_tids.front().first); continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second); } else @@ -1667,40 +1640,28 @@ ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site) { // Try and set hardware breakpoint, and if that fails, fall through // and set a software breakpoint? - } - - if (m_z0_supported) - { - char packet[64]; - const int packet_len = ::snprintf (packet, sizeof(packet), "Z0,%llx,%zx", addr, bp_op_size); - assert (packet_len + 1 < sizeof(packet)); - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true)) + if (m_gdb_comm.SupportsGDBStoppointPacket (eBreakpointHardware)) { - if (response.IsUnsupportedResponse()) - { - // Disable z packet support and try again - m_z0_supported = 0; - return EnableBreakpoint (bp_site); - } - else if (response.IsOKResponse()) + if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size) == 0) { bp_site->SetEnabled(true); - bp_site->SetType (BreakpointSite::eExternal); + bp_site->SetType (BreakpointSite::eHardware); return error; } - else - { - uint8_t error_byte = response.GetError(); - if (error_byte) - error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte); - } } } - else + + if (m_gdb_comm.SupportsGDBStoppointPacket (eBreakpointSoftware)) { - return EnableSoftwareBreakpoint (bp_site); + if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size) == 0) + { + bp_site->SetEnabled(true); + bp_site->SetType (BreakpointSite::eExternal); + return error; + } } + + return EnableSoftwareBreakpoint (bp_site); } if (log) @@ -1731,44 +1692,25 @@ ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site) { const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site); - if (bp_site->IsHardware()) - { - // TODO: disable hardware breakpoint... - } - else + BreakpointSite::Type bp_type = bp_site->GetType(); + switch (bp_type) { - if (m_z0_supported) - { - char packet[64]; - const int packet_len = ::snprintf (packet, sizeof(packet), "z0,%llx,%zx", addr, bp_op_size); - assert (packet_len + 1 < sizeof(packet)); - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true)) - { - if (response.IsUnsupportedResponse()) - { - error.SetErrorString("Breakpoint site was set with Z packet, yet remote debugserver states z packets are not supported."); - } - else if (response.IsOKResponse()) - { - if (log) - log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS", site_id, (uint64_t)addr); - bp_site->SetEnabled(false); - return error; - } - else - { - uint8_t error_byte = response.GetError(); - if (error_byte) - error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte); - } - } - } - else - { - return DisableSoftwareBreakpoint (bp_site); - } + case BreakpointSite::eSoftware: + error = DisableSoftwareBreakpoint (bp_site); + break; + + case BreakpointSite::eHardware: + if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false, addr, bp_op_size)) + error.SetErrorToGenericError(); + break; + + case BreakpointSite::eExternal: + if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false, addr, bp_op_size)) + error.SetErrorToGenericError(); + break; } + if (error.Success()) + bp_site->SetEnabled(false); } else { @@ -1869,16 +1811,7 @@ ProcessGDBRemote::DoSignal (int signo) } Error -ProcessGDBRemote::StartDebugserverProcess -( - const char *debugserver_url, // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...") - char const *inferior_argv[], // Arguments for the inferior program including the path to the inferior itself as the first argument - char const *inferior_envp[], // Environment to pass along to the inferior program - lldb::pid_t attach_pid, // If inferior inferior_argv == NULL, and attach_pid != LLDB_INVALID_PROCESS_ID send this pid as an argument to debugserver - const char *attach_name, // Wait for the next process to launch whose basename matches "attach_name" - bool wait_for_launch, // Wait for the process named "attach_name" to launch - const ArchSpec& inferior_arch // The arch of the inferior that we will launch -) +ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url) // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...") { Error error; if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID) @@ -1886,8 +1819,9 @@ ProcessGDBRemote::StartDebugserverProcess // If we locate debugserver, keep that located version around static FileSpec g_debugserver_file_spec; - FileSpec debugserver_file_spec; + ProcessLaunchInfo launch_info; char debugserver_path[PATH_MAX]; + FileSpec &debugserver_file_spec = launch_info.GetExecutableFile(); // Always check to see if we have an environment override for the path // to the debugserver to use and use it if we do. @@ -1922,25 +1856,10 @@ ProcessGDBRemote::StartDebugserverProcess debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path)); m_stdio_communication.Clear(); - posix_spawnattr_t attr; LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - Error local_err; // Errors that don't affect the spawning. - if (log) - log->Printf ("%s ( path='%s', argv=%p, envp=%p, arch=%s )", - __FUNCTION__, - debugserver_path, - inferior_argv, - inferior_envp, - inferior_arch.GetArchitectureName()); - error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX); - if (error.Fail() || log) - error.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )"); - if (error.Fail()) - return error; - - Args debugserver_args; + Args &debugserver_args = launch_info.GetArguments(); char arg_cstr[PATH_MAX]; // Start args with "debugserver /file/path -r --" @@ -1968,6 +1887,12 @@ ProcessGDBRemote::StartDebugserverProcess // debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt"); // debugserver_args.AppendArgument("--log-flags=0x802e0e"); + // We currently send down all arguments, attach pids, or attach + // process names in dedicated GDB server packets, so we don't need + // to pass them as arguments. This is currently because of all the + // things we need to setup prior to launching: the environment, + // current working dir, file actions, etc. +#if 0 // Now append the program arguments if (inferior_argv) { @@ -1990,20 +1915,18 @@ ProcessGDBRemote::StartDebugserverProcess debugserver_args.AppendArgument ("--attach"); debugserver_args.AppendArgument (attach_name); } - - Error file_actions_err; - posix_spawn_file_actions_t file_actions; -#if DONT_CLOSE_DEBUGSERVER_STDIO - file_actions_err.SetErrorString ("Remove this after uncommenting the code block below."); -#else - file_actions_err.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX); - if (file_actions_err.Success()) - { - ::posix_spawn_file_actions_addclose (&file_actions, STDIN_FILENO); - ::posix_spawn_file_actions_addclose (&file_actions, STDOUT_FILENO); - ::posix_spawn_file_actions_addclose (&file_actions, STDERR_FILENO); - } #endif + + ProcessLaunchInfo::FileAction file_action; + + // Close STDIN, STDOUT and STDERR. We might need to redirect them + // to "/dev/null" if we run into any problems. + file_action.Close (STDIN_FILENO); + launch_info.AppendFileAction (file_action); + file_action.Close (STDOUT_FILENO); + launch_info.AppendFileAction (file_action); + file_action.Close (STDERR_FILENO); + launch_info.AppendFileAction (file_action); if (log) { @@ -2012,28 +1935,15 @@ ProcessGDBRemote::StartDebugserverProcess log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData()); } - error.SetError (::posix_spawnp (&m_debugserver_pid, - debugserver_path, - file_actions_err.Success() ? &file_actions : NULL, - &attr, - debugserver_args.GetArgumentVector(), - (char * const*)inferior_envp), - eErrorTypePOSIX); - - - ::posix_spawnattr_destroy (&attr); - - if (file_actions_err.Success()) - ::posix_spawn_file_actions_destroy (&file_actions); + error = Host::LaunchProcess(launch_info); - // We have seen some cases where posix_spawnp was returning a valid - // looking pid even when an error was returned, so clear it out - if (error.Fail()) + if (error.Success ()) + m_debugserver_pid = launch_info.GetProcessID(); + else m_debugserver_pid = LLDB_INVALID_PROCESS_ID; if (error.Fail() || log) - error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", m_debugserver_pid, debugserver_path, NULL, &attr, inferior_argv, inferior_envp); - + error.PutToLog(log.get(), "Host::LaunchProcess (launch_info) => pid=%i, path='%s'", m_debugserver_pid, debugserver_path); } else { @@ -2143,71 +2053,8 @@ ProcessGDBRemote::Initialize() } bool -ProcessGDBRemote::SetCurrentGDBRemoteThread (int tid) -{ - if (m_curr_tid == tid) - return true; - - char packet[32]; - int packet_len; - if (tid <= 0) - packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid); - else - packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid); - assert (packet_len + 1 < sizeof(packet)); - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false)) - { - if (response.IsOKResponse()) - { - m_curr_tid = tid; - return true; - } - } - return false; -} - -bool -ProcessGDBRemote::SetCurrentGDBRemoteThreadForRun (int tid) -{ - if (m_curr_tid_run == tid) - return true; - - char packet[32]; - int packet_len; - if (tid <= 0) - packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid); - else - packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid); - - assert (packet_len + 1 < sizeof(packet)); - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false)) - { - if (response.IsOKResponse()) - { - m_curr_tid_run = tid; - return true; - } - } - return false; -} - -void -ProcessGDBRemote::ResetGDBRemoteState () -{ - // Reset and GDB remote state - m_curr_tid = LLDB_INVALID_THREAD_ID; - m_curr_tid_run = LLDB_INVALID_THREAD_ID; - m_z0_supported = 1; -} - - -bool ProcessGDBRemote::StartAsyncThread () { - ResetGDBRemoteState (); - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); if (log) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index e9ab4df70f0..cf03604a182 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -215,12 +215,6 @@ protected: friend class GDBRemoteCommunicationClient; friend class GDBRemoteRegisterContext; - bool - SetCurrentGDBRemoteThread (int tid); - - bool - SetCurrentGDBRemoteThreadForRun (int tid); - //---------------------------------------------------------------------- // Accessors //---------------------------------------------------------------------- @@ -275,13 +269,7 @@ protected: UpdateThreadListIfNeeded (); lldb_private::Error - StartDebugserverProcess (const char *debugserver_url, // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...") - char const *inferior_argv[], - char const *inferior_envp[], - lldb::pid_t attach_pid, // If inferior inferior_argv == NULL, then attach to this pid - const char *attach_pid_name, // Wait for the next process to launch whose basename matches "attach_wait_name" - bool wait_for_launch, // Wait for the process named "attach_wait_name" to launch - const lldb_private::ArchSpec& arch_spec); + StartDebugserverProcess (const char *debugserver_url); void KillDebugserverProcess (); @@ -313,11 +301,6 @@ protected: GDBRemoteDynamicRegisterInfo m_register_info; lldb_private::Broadcaster m_async_broadcaster; lldb::thread_t m_async_thread; - // Current GDB remote state. Any members added here need to be reset to - // proper default values in ResetGDBRemoteState (). - lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all other operations - lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for continue, step, etc - uint32_t m_z0_supported:1; // Set to non-zero if Z0 and z0 packets are supported typedef std::vector<lldb::tid_t> tid_collection; typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection; tid_collection m_continue_c_tids; // 'c' for continue @@ -330,9 +313,6 @@ protected: bool m_local_debugserver; // Is the debugserver process we are talking to local or on another machine. std::vector<lldb::user_id_t> m_thread_observation_bps; - void - ResetGDBRemoteState (); - bool StartAsyncThread (); diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 9955409226a..351b6eb2bc9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -261,13 +261,10 @@ ThreadGDBRemote::GetPrivateStopReason () m_thread_stop_reason_stop_id = process_stop_id; m_actual_stop_info_sp.reset(); - char packet[256]; - ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", GetID()); StringExtractorGDBRemote stop_packet; - if (GetGDBProcess().GetGDBRemote().SendPacketAndWaitForResponse(packet, stop_packet, false)) - { - GetGDBProcess().SetThreadStopInfo (stop_packet); - } + ProcessGDBRemote &gdb_process = GetGDBProcess(); + if (gdb_process.GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet)) + gdb_process.SetThreadStopInfo (stop_packet); } return m_actual_stop_info_sp; } |