diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
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; } |