1254721Semaste//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste
11254721Semaste#include "GDBRemoteCommunicationClient.h"
12254721Semaste
13254721Semaste// C Includes
14263363Semaste#include <sys/stat.h>
15263363Semaste
16254721Semaste// C++ Includes
17254721Semaste#include <sstream>
18254721Semaste
19254721Semaste// Other libraries and framework includes
20254721Semaste#include "llvm/ADT/Triple.h"
21254721Semaste#include "lldb/Interpreter/Args.h"
22254721Semaste#include "lldb/Core/ConnectionFileDescriptor.h"
23254721Semaste#include "lldb/Core/Log.h"
24254721Semaste#include "lldb/Core/State.h"
25263363Semaste#include "lldb/Core/StreamGDBRemote.h"
26254721Semaste#include "lldb/Core/StreamString.h"
27254721Semaste#include "lldb/Host/Endian.h"
28254721Semaste#include "lldb/Host/Host.h"
29254721Semaste#include "lldb/Host/TimeValue.h"
30254721Semaste
31254721Semaste// Project includes
32254721Semaste#include "Utility/StringExtractorGDBRemote.h"
33254721Semaste#include "ProcessGDBRemote.h"
34254721Semaste#include "ProcessGDBRemoteLog.h"
35263363Semaste#include "lldb/Host/Config.h"
36254721Semaste
37254721Semasteusing namespace lldb;
38254721Semasteusing namespace lldb_private;
39254721Semaste
40263363Semaste#ifdef LLDB_DISABLE_POSIX
41263363Semaste#define SIGSTOP 17
42263363Semaste#endif
43263363Semaste
44254721Semaste//----------------------------------------------------------------------
45254721Semaste// GDBRemoteCommunicationClient constructor
46254721Semaste//----------------------------------------------------------------------
47254721SemasteGDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
48254721Semaste    GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform),
49254721Semaste    m_supports_not_sending_acks (eLazyBoolCalculate),
50254721Semaste    m_supports_thread_suffix (eLazyBoolCalculate),
51254721Semaste    m_supports_threads_in_stop_reply (eLazyBoolCalculate),
52254721Semaste    m_supports_vCont_all (eLazyBoolCalculate),
53254721Semaste    m_supports_vCont_any (eLazyBoolCalculate),
54254721Semaste    m_supports_vCont_c (eLazyBoolCalculate),
55254721Semaste    m_supports_vCont_C (eLazyBoolCalculate),
56254721Semaste    m_supports_vCont_s (eLazyBoolCalculate),
57254721Semaste    m_supports_vCont_S (eLazyBoolCalculate),
58254721Semaste    m_qHostInfo_is_valid (eLazyBoolCalculate),
59254721Semaste    m_qProcessInfo_is_valid (eLazyBoolCalculate),
60254721Semaste    m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
61254721Semaste    m_supports_memory_region_info  (eLazyBoolCalculate),
62254721Semaste    m_supports_watchpoint_support_info  (eLazyBoolCalculate),
63254721Semaste    m_supports_detach_stay_stopped (eLazyBoolCalculate),
64254721Semaste    m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
65254721Semaste    m_attach_or_wait_reply(eLazyBoolCalculate),
66254721Semaste    m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
67263363Semaste    m_supports_p (eLazyBoolCalculate),
68263367Semaste    m_supports_QSaveRegisterState (eLazyBoolCalculate),
69269024Semaste    m_supports_qXfer_libraries_read (eLazyBoolCalculate),
70269024Semaste    m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate),
71269024Semaste    m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate),
72254721Semaste    m_supports_qProcessInfoPID (true),
73254721Semaste    m_supports_qfProcessInfo (true),
74254721Semaste    m_supports_qUserName (true),
75254721Semaste    m_supports_qGroupName (true),
76254721Semaste    m_supports_qThreadStopInfo (true),
77254721Semaste    m_supports_z0 (true),
78254721Semaste    m_supports_z1 (true),
79254721Semaste    m_supports_z2 (true),
80254721Semaste    m_supports_z3 (true),
81254721Semaste    m_supports_z4 (true),
82263363Semaste    m_supports_QEnvironment (true),
83263363Semaste    m_supports_QEnvironmentHexEncoded (true),
84254721Semaste    m_curr_tid (LLDB_INVALID_THREAD_ID),
85254721Semaste    m_curr_tid_run (LLDB_INVALID_THREAD_ID),
86254721Semaste    m_num_supported_hardware_watchpoints (0),
87254721Semaste    m_async_mutex (Mutex::eMutexTypeRecursive),
88254721Semaste    m_async_packet_predicate (false),
89254721Semaste    m_async_packet (),
90269024Semaste    m_async_result (PacketResult::Success),
91254721Semaste    m_async_response (),
92254721Semaste    m_async_signal (-1),
93254721Semaste    m_thread_id_to_used_usec_map (),
94254721Semaste    m_host_arch(),
95254721Semaste    m_process_arch(),
96254721Semaste    m_os_version_major (UINT32_MAX),
97254721Semaste    m_os_version_minor (UINT32_MAX),
98263363Semaste    m_os_version_update (UINT32_MAX),
99263363Semaste    m_os_build (),
100263363Semaste    m_os_kernel (),
101263363Semaste    m_hostname (),
102269024Semaste    m_default_packet_timeout (0),
103269024Semaste    m_max_packet_size (0)
104254721Semaste{
105254721Semaste}
106254721Semaste
107254721Semaste//----------------------------------------------------------------------
108254721Semaste// Destructor
109254721Semaste//----------------------------------------------------------------------
110254721SemasteGDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
111254721Semaste{
112254721Semaste    if (IsConnected())
113254721Semaste        Disconnect();
114254721Semaste}
115254721Semaste
116254721Semastebool
117254721SemasteGDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
118254721Semaste{
119263367Semaste    ResetDiscoverableSettings();
120263367Semaste
121254721Semaste    // Start the read thread after we send the handshake ack since if we
122254721Semaste    // fail to send the handshake ack, there is no reason to continue...
123254721Semaste    if (SendAck())
124263367Semaste    {
125269024Semaste        // Wait for any responses that might have been queued up in the remote
126269024Semaste        // GDB server and flush them all
127269024Semaste        StringExtractorGDBRemote response;
128269024Semaste        PacketResult packet_result = PacketResult::Success;
129269024Semaste        const uint32_t timeout_usec = 10 * 1000; // Wait for 10 ms for a response
130269024Semaste        while (packet_result == PacketResult::Success)
131269024Semaste            packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (response, timeout_usec);
132269024Semaste
133263367Semaste        // The return value from QueryNoAckModeSupported() is true if the packet
134263367Semaste        // was sent and _any_ response (including UNIMPLEMENTED) was received),
135263367Semaste        // or false if no response was received. This quickly tells us if we have
136263367Semaste        // a live connection to a remote GDB server...
137263367Semaste        if (QueryNoAckModeSupported())
138263367Semaste        {
139269024Semaste#if 0
140269024Semaste            // Set above line to "#if 1" to test packet speed if remote GDB server
141269024Semaste            // supports the qSpeedTest packet...
142269024Semaste            TestPacketSpeed(10000);
143269024Semaste#endif
144263367Semaste            return true;
145263367Semaste        }
146263367Semaste        else
147263367Semaste        {
148263367Semaste            if (error_ptr)
149263367Semaste                error_ptr->SetErrorString("failed to get reply to handshake packet");
150263367Semaste        }
151263367Semaste    }
152263367Semaste    else
153263367Semaste    {
154263367Semaste        if (error_ptr)
155263367Semaste            error_ptr->SetErrorString("failed to send the handshake ack");
156263367Semaste    }
157254721Semaste    return false;
158254721Semaste}
159254721Semaste
160263367Semastebool
161269024SemasteGDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported ()
162269024Semaste{
163269024Semaste    if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate)
164269024Semaste    {
165269024Semaste        GetRemoteQSupported();
166269024Semaste    }
167269024Semaste    return (m_supports_augmented_libraries_svr4_read == eLazyBoolYes);
168269024Semaste}
169269024Semaste
170269024Semastebool
171269024SemasteGDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported ()
172269024Semaste{
173269024Semaste    if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate)
174269024Semaste    {
175269024Semaste        GetRemoteQSupported();
176269024Semaste    }
177269024Semaste    return (m_supports_qXfer_libraries_svr4_read == eLazyBoolYes);
178269024Semaste}
179269024Semaste
180269024Semastebool
181269024SemasteGDBRemoteCommunicationClient::GetQXferLibrariesReadSupported ()
182269024Semaste{
183269024Semaste    if (m_supports_qXfer_libraries_read == eLazyBoolCalculate)
184269024Semaste    {
185269024Semaste        GetRemoteQSupported();
186269024Semaste    }
187269024Semaste    return (m_supports_qXfer_libraries_read == eLazyBoolYes);
188269024Semaste}
189269024Semaste
190269024Semasteuint64_t
191269024SemasteGDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
192269024Semaste{
193269024Semaste    if (m_max_packet_size == 0)
194269024Semaste    {
195269024Semaste        GetRemoteQSupported();
196269024Semaste    }
197269024Semaste    return m_max_packet_size;
198269024Semaste}
199269024Semaste
200269024Semastebool
201254721SemasteGDBRemoteCommunicationClient::QueryNoAckModeSupported ()
202254721Semaste{
203254721Semaste    if (m_supports_not_sending_acks == eLazyBoolCalculate)
204254721Semaste    {
205254721Semaste        m_send_acks = true;
206254721Semaste        m_supports_not_sending_acks = eLazyBoolNo;
207254721Semaste
208254721Semaste        StringExtractorGDBRemote response;
209269024Semaste        if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == PacketResult::Success)
210254721Semaste        {
211254721Semaste            if (response.IsOKResponse())
212254721Semaste            {
213254721Semaste                m_send_acks = false;
214254721Semaste                m_supports_not_sending_acks = eLazyBoolYes;
215254721Semaste            }
216263367Semaste            return true;
217254721Semaste        }
218254721Semaste    }
219263367Semaste    return false;
220254721Semaste}
221254721Semaste
222254721Semastevoid
223254721SemasteGDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
224254721Semaste{
225254721Semaste    if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
226254721Semaste    {
227254721Semaste        m_supports_threads_in_stop_reply = eLazyBoolNo;
228254721Semaste
229254721Semaste        StringExtractorGDBRemote response;
230269024Semaste        if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false) == PacketResult::Success)
231254721Semaste        {
232254721Semaste            if (response.IsOKResponse())
233254721Semaste                m_supports_threads_in_stop_reply = eLazyBoolYes;
234254721Semaste        }
235254721Semaste    }
236254721Semaste}
237254721Semaste
238254721Semastebool
239254721SemasteGDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
240254721Semaste{
241254721Semaste    if (m_attach_or_wait_reply == eLazyBoolCalculate)
242254721Semaste    {
243254721Semaste        m_attach_or_wait_reply = eLazyBoolNo;
244254721Semaste
245254721Semaste        StringExtractorGDBRemote response;
246269024Semaste        if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false) == PacketResult::Success)
247254721Semaste        {
248254721Semaste            if (response.IsOKResponse())
249254721Semaste                m_attach_or_wait_reply = eLazyBoolYes;
250254721Semaste        }
251254721Semaste    }
252254721Semaste    if (m_attach_or_wait_reply == eLazyBoolYes)
253254721Semaste        return true;
254254721Semaste    else
255254721Semaste        return false;
256254721Semaste}
257254721Semaste
258254721Semastebool
259254721SemasteGDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
260254721Semaste{
261254721Semaste    if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate)
262254721Semaste    {
263254721Semaste        m_prepare_for_reg_writing_reply = eLazyBoolNo;
264254721Semaste
265254721Semaste        StringExtractorGDBRemote response;
266269024Semaste        if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false) == PacketResult::Success)
267254721Semaste        {
268254721Semaste            if (response.IsOKResponse())
269254721Semaste                m_prepare_for_reg_writing_reply = eLazyBoolYes;
270254721Semaste        }
271254721Semaste    }
272254721Semaste    if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
273254721Semaste        return true;
274254721Semaste    else
275254721Semaste        return false;
276254721Semaste}
277254721Semaste
278254721Semaste
279254721Semastevoid
280254721SemasteGDBRemoteCommunicationClient::ResetDiscoverableSettings()
281254721Semaste{
282254721Semaste    m_supports_not_sending_acks = eLazyBoolCalculate;
283254721Semaste    m_supports_thread_suffix = eLazyBoolCalculate;
284254721Semaste    m_supports_threads_in_stop_reply = eLazyBoolCalculate;
285254721Semaste    m_supports_vCont_c = eLazyBoolCalculate;
286254721Semaste    m_supports_vCont_C = eLazyBoolCalculate;
287254721Semaste    m_supports_vCont_s = eLazyBoolCalculate;
288254721Semaste    m_supports_vCont_S = eLazyBoolCalculate;
289263363Semaste    m_supports_p = eLazyBoolCalculate;
290263367Semaste    m_supports_QSaveRegisterState = eLazyBoolCalculate;
291254721Semaste    m_qHostInfo_is_valid = eLazyBoolCalculate;
292254721Semaste    m_qProcessInfo_is_valid = eLazyBoolCalculate;
293254721Semaste    m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
294254721Semaste    m_supports_memory_region_info = eLazyBoolCalculate;
295254721Semaste    m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
296254721Semaste    m_attach_or_wait_reply = eLazyBoolCalculate;
297269024Semaste    m_supports_qXfer_libraries_read = eLazyBoolCalculate;
298269024Semaste    m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
299269024Semaste    m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
300254721Semaste
301254721Semaste    m_supports_qProcessInfoPID = true;
302254721Semaste    m_supports_qfProcessInfo = true;
303254721Semaste    m_supports_qUserName = true;
304254721Semaste    m_supports_qGroupName = true;
305254721Semaste    m_supports_qThreadStopInfo = true;
306254721Semaste    m_supports_z0 = true;
307254721Semaste    m_supports_z1 = true;
308254721Semaste    m_supports_z2 = true;
309254721Semaste    m_supports_z3 = true;
310254721Semaste    m_supports_z4 = true;
311263363Semaste    m_supports_QEnvironment = true;
312263363Semaste    m_supports_QEnvironmentHexEncoded = true;
313254721Semaste    m_host_arch.Clear();
314254721Semaste    m_process_arch.Clear();
315269024Semaste
316269024Semaste    m_max_packet_size = 0;
317254721Semaste}
318254721Semaste
319269024Semastevoid
320269024SemasteGDBRemoteCommunicationClient::GetRemoteQSupported ()
321269024Semaste{
322269024Semaste    // Clear out any capabilities we expect to see in the qSupported response
323269024Semaste    m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
324269024Semaste    m_supports_qXfer_libraries_read = eLazyBoolNo;
325269024Semaste    m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
326269024Semaste    m_max_packet_size = UINT64_MAX;  // It's supposed to always be there, but if not, we assume no limit
327254721Semaste
328269024Semaste    StringExtractorGDBRemote response;
329269024Semaste    if (SendPacketAndWaitForResponse("qSupported",
330269024Semaste                                     response,
331269024Semaste                                     /*send_async=*/false) == PacketResult::Success)
332269024Semaste    {
333269024Semaste        const char *response_cstr = response.GetStringRef().c_str();
334269024Semaste        if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
335269024Semaste            m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
336269024Semaste        if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
337269024Semaste        {
338269024Semaste            m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;  // implied
339269024Semaste            m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
340269024Semaste        }
341269024Semaste        if (::strstr (response_cstr, "qXfer:libraries:read+"))
342269024Semaste            m_supports_qXfer_libraries_read = eLazyBoolYes;
343269024Semaste
344269024Semaste        const char *packet_size_str = ::strstr (response_cstr, "PacketSize=");
345269024Semaste        if (packet_size_str)
346269024Semaste        {
347269024Semaste            StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));
348269024Semaste            m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
349269024Semaste            if (m_max_packet_size == 0)
350269024Semaste            {
351269024Semaste                m_max_packet_size = UINT64_MAX;  // Must have been a garbled response
352269024Semaste                Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
353269024Semaste                if (log)
354269024Semaste                    log->Printf ("Garbled PacketSize spec in qSupported response");
355269024Semaste            }
356269024Semaste        }
357269024Semaste    }
358269024Semaste}
359269024Semaste
360254721Semastebool
361254721SemasteGDBRemoteCommunicationClient::GetThreadSuffixSupported ()
362254721Semaste{
363254721Semaste    if (m_supports_thread_suffix == eLazyBoolCalculate)
364254721Semaste    {
365254721Semaste        StringExtractorGDBRemote response;
366254721Semaste        m_supports_thread_suffix = eLazyBoolNo;
367269024Semaste        if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false) == PacketResult::Success)
368254721Semaste        {
369254721Semaste            if (response.IsOKResponse())
370254721Semaste                m_supports_thread_suffix = eLazyBoolYes;
371254721Semaste        }
372254721Semaste    }
373254721Semaste    return m_supports_thread_suffix;
374254721Semaste}
375254721Semastebool
376254721SemasteGDBRemoteCommunicationClient::GetVContSupported (char flavor)
377254721Semaste{
378254721Semaste    if (m_supports_vCont_c == eLazyBoolCalculate)
379254721Semaste    {
380254721Semaste        StringExtractorGDBRemote response;
381254721Semaste        m_supports_vCont_any = eLazyBoolNo;
382254721Semaste        m_supports_vCont_all = eLazyBoolNo;
383254721Semaste        m_supports_vCont_c = eLazyBoolNo;
384254721Semaste        m_supports_vCont_C = eLazyBoolNo;
385254721Semaste        m_supports_vCont_s = eLazyBoolNo;
386254721Semaste        m_supports_vCont_S = eLazyBoolNo;
387269024Semaste        if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success)
388254721Semaste        {
389254721Semaste            const char *response_cstr = response.GetStringRef().c_str();
390254721Semaste            if (::strstr (response_cstr, ";c"))
391254721Semaste                m_supports_vCont_c = eLazyBoolYes;
392254721Semaste
393254721Semaste            if (::strstr (response_cstr, ";C"))
394254721Semaste                m_supports_vCont_C = eLazyBoolYes;
395254721Semaste
396254721Semaste            if (::strstr (response_cstr, ";s"))
397254721Semaste                m_supports_vCont_s = eLazyBoolYes;
398254721Semaste
399254721Semaste            if (::strstr (response_cstr, ";S"))
400254721Semaste                m_supports_vCont_S = eLazyBoolYes;
401254721Semaste
402254721Semaste            if (m_supports_vCont_c == eLazyBoolYes &&
403254721Semaste                m_supports_vCont_C == eLazyBoolYes &&
404254721Semaste                m_supports_vCont_s == eLazyBoolYes &&
405254721Semaste                m_supports_vCont_S == eLazyBoolYes)
406254721Semaste            {
407254721Semaste                m_supports_vCont_all = eLazyBoolYes;
408254721Semaste            }
409254721Semaste
410254721Semaste            if (m_supports_vCont_c == eLazyBoolYes ||
411254721Semaste                m_supports_vCont_C == eLazyBoolYes ||
412254721Semaste                m_supports_vCont_s == eLazyBoolYes ||
413254721Semaste                m_supports_vCont_S == eLazyBoolYes)
414254721Semaste            {
415254721Semaste                m_supports_vCont_any = eLazyBoolYes;
416254721Semaste            }
417254721Semaste        }
418254721Semaste    }
419254721Semaste
420254721Semaste    switch (flavor)
421254721Semaste    {
422254721Semaste    case 'a': return m_supports_vCont_any;
423254721Semaste    case 'A': return m_supports_vCont_all;
424254721Semaste    case 'c': return m_supports_vCont_c;
425254721Semaste    case 'C': return m_supports_vCont_C;
426254721Semaste    case 's': return m_supports_vCont_s;
427254721Semaste    case 'S': return m_supports_vCont_S;
428254721Semaste    default: break;
429254721Semaste    }
430254721Semaste    return false;
431254721Semaste}
432254721Semaste
433263363Semaste// Check if the target supports 'p' packet. It sends out a 'p'
434263363Semaste// packet and checks the response. A normal packet will tell us
435263363Semaste// that support is available.
436263363Semaste//
437263363Semaste// Takes a valid thread ID because p needs to apply to a thread.
438263363Semastebool
439263363SemasteGDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
440263363Semaste{
441263363Semaste    if (m_supports_p == eLazyBoolCalculate)
442263363Semaste    {
443263363Semaste        StringExtractorGDBRemote response;
444263363Semaste        m_supports_p = eLazyBoolNo;
445263363Semaste        char packet[256];
446263363Semaste        if (GetThreadSuffixSupported())
447263363Semaste            snprintf(packet, sizeof(packet), "p0;thread:%" PRIx64 ";", tid);
448263363Semaste        else
449263363Semaste            snprintf(packet, sizeof(packet), "p0");
450263363Semaste
451269024Semaste        if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
452263363Semaste        {
453263363Semaste            if (response.IsNormalResponse())
454263363Semaste                m_supports_p = eLazyBoolYes;
455263363Semaste        }
456263363Semaste    }
457263363Semaste    return m_supports_p;
458263363Semaste}
459254721Semaste
460269024SemasteGDBRemoteCommunicationClient::PacketResult
461269024SemasteGDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses
462269024Semaste(
463269024Semaste    const char *payload_prefix,
464269024Semaste    std::string &response_string
465269024Semaste)
466269024Semaste{
467269024Semaste    Mutex::Locker locker;
468269024Semaste    if (!GetSequenceMutex(locker,
469269024Semaste                          "ProcessGDBRemote::SendPacketsAndConcatenateResponses() failed due to not getting the sequence mutex"))
470269024Semaste    {
471269024Semaste        Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
472269024Semaste        if (log)
473269024Semaste            log->Printf("error: failed to get packet sequence mutex, not sending packets with prefix '%s'",
474269024Semaste                        payload_prefix);
475269024Semaste        return PacketResult::ErrorNoSequenceLock;
476269024Semaste    }
477269024Semaste
478269024Semaste    response_string = "";
479269024Semaste    std::string payload_prefix_str(payload_prefix);
480269024Semaste    unsigned int response_size = 0x1000;
481269024Semaste    if (response_size > GetRemoteMaxPacketSize()) {  // May send qSupported packet
482269024Semaste        response_size = GetRemoteMaxPacketSize();
483269024Semaste    }
484269024Semaste
485269024Semaste    for (unsigned int offset = 0; true; offset += response_size)
486269024Semaste    {
487269024Semaste        StringExtractorGDBRemote this_response;
488269024Semaste        // Construct payload
489269024Semaste        char sizeDescriptor[128];
490269024Semaste        snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset, response_size);
491269024Semaste        PacketResult result = SendPacketAndWaitForResponse((payload_prefix_str + sizeDescriptor).c_str(),
492269024Semaste                                                           this_response,
493269024Semaste                                                           /*send_async=*/false);
494269024Semaste        if (result != PacketResult::Success)
495269024Semaste            return result;
496269024Semaste
497269024Semaste        const std::string &this_string = this_response.GetStringRef();
498269024Semaste
499269024Semaste        // Check for m or l as first character; l seems to mean this is the last chunk
500269024Semaste        char first_char = *this_string.c_str();
501269024Semaste        if (first_char != 'm' && first_char != 'l')
502269024Semaste        {
503269024Semaste            return PacketResult::ErrorReplyInvalid;
504269024Semaste        }
505269024Semaste        // Skip past m or l
506269024Semaste        const char *s = this_string.c_str() + 1;
507269024Semaste
508269024Semaste        // Concatenate the result so far
509269024Semaste        response_string += s;
510269024Semaste        if (first_char == 'l')
511269024Semaste            // We're done
512269024Semaste            return PacketResult::Success;
513269024Semaste    }
514269024Semaste}
515269024Semaste
516269024SemasteGDBRemoteCommunicationClient::PacketResult
517254721SemasteGDBRemoteCommunicationClient::SendPacketAndWaitForResponse
518254721Semaste(
519254721Semaste    const char *payload,
520254721Semaste    StringExtractorGDBRemote &response,
521254721Semaste    bool send_async
522254721Semaste)
523254721Semaste{
524254721Semaste    return SendPacketAndWaitForResponse (payload,
525254721Semaste                                         ::strlen (payload),
526254721Semaste                                         response,
527254721Semaste                                         send_async);
528254721Semaste}
529254721Semaste
530269024SemasteGDBRemoteCommunicationClient::PacketResult
531269024SemasteGDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *payload,
532269024Semaste                                                                  size_t payload_length,
533269024Semaste                                                                  StringExtractorGDBRemote &response)
534269024Semaste{
535269024Semaste    PacketResult packet_result = SendPacketNoLock (payload, payload_length);
536269024Semaste    if (packet_result == PacketResult::Success)
537269024Semaste        packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
538269024Semaste    return packet_result;
539269024Semaste}
540269024Semaste
541269024SemasteGDBRemoteCommunicationClient::PacketResult
542254721SemasteGDBRemoteCommunicationClient::SendPacketAndWaitForResponse
543254721Semaste(
544254721Semaste    const char *payload,
545254721Semaste    size_t payload_length,
546254721Semaste    StringExtractorGDBRemote &response,
547254721Semaste    bool send_async
548254721Semaste)
549254721Semaste{
550269024Semaste    PacketResult packet_result = PacketResult::ErrorSendFailed;
551254721Semaste    Mutex::Locker locker;
552254721Semaste    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
553254721Semaste    size_t response_len = 0;
554254721Semaste    if (GetSequenceMutex (locker))
555254721Semaste    {
556269024Semaste        packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
557254721Semaste    }
558254721Semaste    else
559254721Semaste    {
560254721Semaste        if (send_async)
561254721Semaste        {
562254721Semaste            if (IsRunning())
563254721Semaste            {
564254721Semaste                Mutex::Locker async_locker (m_async_mutex);
565254721Semaste                m_async_packet.assign(payload, payload_length);
566254721Semaste                m_async_packet_predicate.SetValue (true, eBroadcastNever);
567254721Semaste
568254721Semaste                if (log)
569254721Semaste                    log->Printf ("async: async packet = %s", m_async_packet.c_str());
570254721Semaste
571254721Semaste                bool timed_out = false;
572254721Semaste                if (SendInterrupt(locker, 2, timed_out))
573254721Semaste                {
574254721Semaste                    if (m_interrupt_sent)
575254721Semaste                    {
576254721Semaste                        m_interrupt_sent = false;
577254721Semaste                        TimeValue timeout_time;
578254721Semaste                        timeout_time = TimeValue::Now();
579254721Semaste                        timeout_time.OffsetWithSeconds (m_packet_timeout);
580254721Semaste
581254721Semaste                        if (log)
582254721Semaste                            log->Printf ("async: sent interrupt");
583254721Semaste
584254721Semaste                        if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
585254721Semaste                        {
586254721Semaste                            if (log)
587254721Semaste                                log->Printf ("async: got response");
588254721Semaste
589254721Semaste                            // Swap the response buffer to avoid malloc and string copy
590254721Semaste                            response.GetStringRef().swap (m_async_response.GetStringRef());
591254721Semaste                            response_len = response.GetStringRef().size();
592269024Semaste                            packet_result = m_async_result;
593254721Semaste                        }
594254721Semaste                        else
595254721Semaste                        {
596254721Semaste                            if (log)
597254721Semaste                                log->Printf ("async: timed out waiting for response");
598254721Semaste                        }
599254721Semaste
600254721Semaste                        // Make sure we wait until the continue packet has been sent again...
601254721Semaste                        if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
602254721Semaste                        {
603254721Semaste                            if (log)
604254721Semaste                            {
605254721Semaste                                if (timed_out)
606254721Semaste                                    log->Printf ("async: timed out waiting for process to resume, but process was resumed");
607254721Semaste                                else
608254721Semaste                                    log->Printf ("async: async packet sent");
609254721Semaste                            }
610254721Semaste                        }
611254721Semaste                        else
612254721Semaste                        {
613254721Semaste                            if (log)
614254721Semaste                                log->Printf ("async: timed out waiting for process to resume");
615254721Semaste                        }
616254721Semaste                    }
617254721Semaste                    else
618254721Semaste                    {
619254721Semaste                        // We had a racy condition where we went to send the interrupt
620254721Semaste                        // yet we were able to get the lock, so the process must have
621254721Semaste                        // just stopped?
622254721Semaste                        if (log)
623254721Semaste                            log->Printf ("async: got lock without sending interrupt");
624254721Semaste                        // Send the packet normally since we got the lock
625269024Semaste                        packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
626254721Semaste                    }
627254721Semaste                }
628254721Semaste                else
629254721Semaste                {
630254721Semaste                    if (log)
631254721Semaste                        log->Printf ("async: failed to interrupt");
632254721Semaste                }
633254721Semaste            }
634254721Semaste            else
635254721Semaste            {
636254721Semaste                if (log)
637254721Semaste                    log->Printf ("async: not running, async is ignored");
638254721Semaste            }
639254721Semaste        }
640254721Semaste        else
641254721Semaste        {
642254721Semaste            if (log)
643254721Semaste                log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload);
644254721Semaste        }
645254721Semaste    }
646269024Semaste    return packet_result;
647254721Semaste}
648254721Semaste
649254721Semastestatic const char *end_delimiter = "--end--;";
650254721Semastestatic const int end_delimiter_len = 8;
651254721Semaste
652254721Semastestd::string
653254721SemasteGDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
654254721Semaste(   ProcessGDBRemote *process,
655254721Semaste    StringExtractorGDBRemote& profileDataExtractor
656254721Semaste)
657254721Semaste{
658254721Semaste    std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
659254721Semaste    std::stringstream final_output;
660254721Semaste    std::string name, value;
661254721Semaste
662254721Semaste    // Going to assuming thread_used_usec comes first, else bail out.
663254721Semaste    while (profileDataExtractor.GetNameColonValue(name, value))
664254721Semaste    {
665254721Semaste        if (name.compare("thread_used_id") == 0)
666254721Semaste        {
667254721Semaste            StringExtractor threadIDHexExtractor(value.c_str());
668254721Semaste            uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
669254721Semaste
670254721Semaste            bool has_used_usec = false;
671254721Semaste            uint32_t curr_used_usec = 0;
672254721Semaste            std::string usec_name, usec_value;
673254721Semaste            uint32_t input_file_pos = profileDataExtractor.GetFilePos();
674254721Semaste            if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
675254721Semaste            {
676254721Semaste                if (usec_name.compare("thread_used_usec") == 0)
677254721Semaste                {
678254721Semaste                    has_used_usec = true;
679254721Semaste                    curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
680254721Semaste                }
681254721Semaste                else
682254721Semaste                {
683254721Semaste                    // We didn't find what we want, it is probably
684254721Semaste                    // an older version. Bail out.
685254721Semaste                    profileDataExtractor.SetFilePos(input_file_pos);
686254721Semaste                }
687254721Semaste            }
688254721Semaste
689254721Semaste            if (has_used_usec)
690254721Semaste            {
691254721Semaste                uint32_t prev_used_usec = 0;
692254721Semaste                std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
693254721Semaste                if (iterator != m_thread_id_to_used_usec_map.end())
694254721Semaste                {
695254721Semaste                    prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
696254721Semaste                }
697254721Semaste
698254721Semaste                uint32_t real_used_usec = curr_used_usec - prev_used_usec;
699254721Semaste                // A good first time record is one that runs for at least 0.25 sec
700254721Semaste                bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
701254721Semaste                bool good_subsequent_time = (prev_used_usec > 0) &&
702254721Semaste                    ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
703254721Semaste
704254721Semaste                if (good_first_time || good_subsequent_time)
705254721Semaste                {
706254721Semaste                    // We try to avoid doing too many index id reservation,
707254721Semaste                    // resulting in fast increase of index ids.
708254721Semaste
709254721Semaste                    final_output << name << ":";
710254721Semaste                    int32_t index_id = process->AssignIndexIDToThread(thread_id);
711254721Semaste                    final_output << index_id << ";";
712254721Semaste
713254721Semaste                    final_output << usec_name << ":" << usec_value << ";";
714254721Semaste                }
715254721Semaste                else
716254721Semaste                {
717254721Semaste                    // Skip past 'thread_used_name'.
718254721Semaste                    std::string local_name, local_value;
719254721Semaste                    profileDataExtractor.GetNameColonValue(local_name, local_value);
720254721Semaste                }
721254721Semaste
722254721Semaste                // Store current time as previous time so that they can be compared later.
723254721Semaste                new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
724254721Semaste            }
725254721Semaste            else
726254721Semaste            {
727254721Semaste                // Bail out and use old string.
728254721Semaste                final_output << name << ":" << value << ";";
729254721Semaste            }
730254721Semaste        }
731254721Semaste        else
732254721Semaste        {
733254721Semaste            final_output << name << ":" << value << ";";
734254721Semaste        }
735254721Semaste    }
736254721Semaste    final_output << end_delimiter;
737254721Semaste    m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
738254721Semaste
739254721Semaste    return final_output.str();
740254721Semaste}
741254721Semaste
742254721SemasteStateType
743254721SemasteGDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
744254721Semaste(
745254721Semaste    ProcessGDBRemote *process,
746254721Semaste    const char *payload,
747254721Semaste    size_t packet_length,
748254721Semaste    StringExtractorGDBRemote &response
749254721Semaste)
750254721Semaste{
751254721Semaste    m_curr_tid = LLDB_INVALID_THREAD_ID;
752254721Semaste    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
753254721Semaste    if (log)
754254721Semaste        log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
755254721Semaste
756254721Semaste    Mutex::Locker locker(m_sequence_mutex);
757254721Semaste    StateType state = eStateRunning;
758254721Semaste
759254721Semaste    BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
760254721Semaste    m_public_is_running.SetValue (true, eBroadcastNever);
761254721Semaste    // Set the starting continue packet into "continue_packet". This packet
762254721Semaste    // may change if we are interrupted and we continue after an async packet...
763254721Semaste    std::string continue_packet(payload, packet_length);
764254721Semaste
765254721Semaste    bool got_async_packet = false;
766254721Semaste
767254721Semaste    while (state == eStateRunning)
768254721Semaste    {
769254721Semaste        if (!got_async_packet)
770254721Semaste        {
771254721Semaste            if (log)
772254721Semaste                log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
773269024Semaste            if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
774254721Semaste                state = eStateInvalid;
775254721Semaste
776254721Semaste            m_private_is_running.SetValue (true, eBroadcastAlways);
777254721Semaste        }
778254721Semaste
779254721Semaste        got_async_packet = false;
780254721Semaste
781254721Semaste        if (log)
782254721Semaste            log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str());
783254721Semaste
784269024Semaste        if (WaitForPacketWithTimeoutMicroSecondsNoLock(response, UINT32_MAX) == PacketResult::Success)
785254721Semaste        {
786254721Semaste            if (response.Empty())
787254721Semaste                state = eStateInvalid;
788254721Semaste            else
789254721Semaste            {
790254721Semaste                const char stop_type = response.GetChar();
791254721Semaste                if (log)
792254721Semaste                    log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
793254721Semaste                switch (stop_type)
794254721Semaste                {
795254721Semaste                case 'T':
796254721Semaste                case 'S':
797254721Semaste                    {
798254721Semaste                        if (process->GetStopID() == 0)
799254721Semaste                        {
800254721Semaste                            if (process->GetID() == LLDB_INVALID_PROCESS_ID)
801254721Semaste                            {
802254721Semaste                                lldb::pid_t pid = GetCurrentProcessID ();
803254721Semaste                                if (pid != LLDB_INVALID_PROCESS_ID)
804254721Semaste                                    process->SetID (pid);
805254721Semaste                            }
806254721Semaste                            process->BuildDynamicRegisterInfo (true);
807254721Semaste                        }
808254721Semaste
809254721Semaste                        // Privately notify any internal threads that we have stopped
810254721Semaste                        // in case we wanted to interrupt our process, yet we might
811254721Semaste                        // send a packet and continue without returning control to the
812254721Semaste                        // user.
813254721Semaste                        m_private_is_running.SetValue (false, eBroadcastAlways);
814254721Semaste
815254721Semaste                        const uint8_t signo = response.GetHexU8 (UINT8_MAX);
816254721Semaste
817254721Semaste                        bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue();
818254721Semaste                        if (continue_after_async || m_interrupt_sent)
819254721Semaste                        {
820254721Semaste                            // We sent an interrupt packet to stop the inferior process
821254721Semaste                            // for an async signal or to send an async packet while running
822254721Semaste                            // but we might have been single stepping and received the
823254721Semaste                            // stop packet for the step instead of for the interrupt packet.
824254721Semaste                            // Typically when an interrupt is sent a SIGINT or SIGSTOP
825254721Semaste                            // is used, so if we get anything else, we need to try and
826254721Semaste                            // get another stop reply packet that may have been sent
827254721Semaste                            // due to sending the interrupt when the target is stopped
828254721Semaste                            // which will just re-send a copy of the last stop reply
829254721Semaste                            // packet. If we don't do this, then the reply for our
830254721Semaste                            // async packet will be the repeat stop reply packet and cause
831254721Semaste                            // a lot of trouble for us!
832254721Semaste                            if (signo != SIGINT && signo != SIGSTOP)
833254721Semaste                            {
834254721Semaste                                continue_after_async = false;
835254721Semaste
836254721Semaste                                // We didn't get a a SIGINT or SIGSTOP, so try for a
837254721Semaste                                // very brief time (1 ms) to get another stop reply
838254721Semaste                                // packet to make sure it doesn't get in the way
839254721Semaste                                StringExtractorGDBRemote extra_stop_reply_packet;
840254721Semaste                                uint32_t timeout_usec = 1000;
841269024Semaste                                if (WaitForPacketWithTimeoutMicroSecondsNoLock (extra_stop_reply_packet, timeout_usec) == PacketResult::Success)
842254721Semaste                                {
843254721Semaste                                    switch (extra_stop_reply_packet.GetChar())
844254721Semaste                                    {
845254721Semaste                                    case 'T':
846254721Semaste                                    case 'S':
847254721Semaste                                        // We did get an extra stop reply, which means
848254721Semaste                                        // our interrupt didn't stop the target so we
849254721Semaste                                        // shouldn't continue after the async signal
850254721Semaste                                        // or packet is sent...
851254721Semaste                                        continue_after_async = false;
852254721Semaste                                        break;
853254721Semaste                                    }
854254721Semaste                                }
855254721Semaste                            }
856254721Semaste                        }
857254721Semaste
858254721Semaste                        if (m_async_signal != -1)
859254721Semaste                        {
860254721Semaste                            if (log)
861254721Semaste                                log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
862254721Semaste
863254721Semaste                            // Save off the async signal we are supposed to send
864254721Semaste                            const int async_signal = m_async_signal;
865254721Semaste                            // Clear the async signal member so we don't end up
866254721Semaste                            // sending the signal multiple times...
867254721Semaste                            m_async_signal = -1;
868254721Semaste                            // Check which signal we stopped with
869254721Semaste                            if (signo == async_signal)
870254721Semaste                            {
871254721Semaste                                if (log)
872254721Semaste                                    log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
873254721Semaste
874254721Semaste                                // We already stopped with a signal that we wanted
875254721Semaste                                // to stop with, so we are done
876254721Semaste                            }
877254721Semaste                            else
878254721Semaste                            {
879254721Semaste                                // We stopped with a different signal that the one
880254721Semaste                                // we wanted to stop with, so now we must resume
881254721Semaste                                // with the signal we want
882254721Semaste                                char signal_packet[32];
883254721Semaste                                int signal_packet_len = 0;
884254721Semaste                                signal_packet_len = ::snprintf (signal_packet,
885254721Semaste                                                                sizeof (signal_packet),
886254721Semaste                                                                "C%2.2x",
887254721Semaste                                                                async_signal);
888254721Semaste
889254721Semaste                                if (log)
890254721Semaste                                    log->Printf ("async: stopped with signal %s, resume with %s",
891254721Semaste                                                       Host::GetSignalAsCString (signo),
892254721Semaste                                                       Host::GetSignalAsCString (async_signal));
893254721Semaste
894254721Semaste                                // Set the continue packet to resume even if the
895254721Semaste                                // interrupt didn't cause our stop (ignore continue_after_async)
896254721Semaste                                continue_packet.assign(signal_packet, signal_packet_len);
897254721Semaste                                continue;
898254721Semaste                            }
899254721Semaste                        }
900254721Semaste                        else if (m_async_packet_predicate.GetValue())
901254721Semaste                        {
902254721Semaste                            Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
903254721Semaste
904254721Semaste                            // We are supposed to send an asynchronous packet while
905269024Semaste                            // we are running.
906254721Semaste                            m_async_response.Clear();
907254721Semaste                            if (m_async_packet.empty())
908254721Semaste                            {
909269024Semaste                                m_async_result = PacketResult::ErrorSendFailed;
910269024Semaste                                if (packet_log)
911254721Semaste                                    packet_log->Printf ("async: error: empty async packet");
912254721Semaste
913254721Semaste                            }
914254721Semaste                            else
915254721Semaste                            {
916254721Semaste                                if (packet_log)
917254721Semaste                                    packet_log->Printf ("async: sending packet");
918254721Semaste
919269024Semaste                                m_async_result = SendPacketAndWaitForResponse (&m_async_packet[0],
920269024Semaste                                                                               m_async_packet.size(),
921269024Semaste                                                                               m_async_response,
922269024Semaste                                                                               false);
923254721Semaste                            }
924254721Semaste                            // Let the other thread that was trying to send the async
925254721Semaste                            // packet know that the packet has been sent and response is
926254721Semaste                            // ready...
927254721Semaste                            m_async_packet_predicate.SetValue(false, eBroadcastAlways);
928254721Semaste
929254721Semaste                            if (packet_log)
930254721Semaste                                packet_log->Printf ("async: sent packet, continue_after_async = %i", continue_after_async);
931254721Semaste
932254721Semaste                            // Set the continue packet to resume if our interrupt
933254721Semaste                            // for the async packet did cause the stop
934254721Semaste                            if (continue_after_async)
935254721Semaste                            {
936254721Semaste                                // Reverting this for now as it is causing deadlocks
937254721Semaste                                // in programs (<rdar://problem/11529853>). In the future
938254721Semaste                                // we should check our thread list and "do the right thing"
939254721Semaste                                // for new threads that show up while we stop and run async
940254721Semaste                                // packets. Setting the packet to 'c' to continue all threads
941254721Semaste                                // is the right thing to do 99.99% of the time because if a
942254721Semaste                                // thread was single stepping, and we sent an interrupt, we
943254721Semaste                                // will notice above that we didn't stop due to an interrupt
944254721Semaste                                // but stopped due to stepping and we would _not_ continue.
945254721Semaste                                continue_packet.assign (1, 'c');
946254721Semaste                                continue;
947254721Semaste                            }
948254721Semaste                        }
949254721Semaste                        // Stop with signal and thread info
950254721Semaste                        state = eStateStopped;
951254721Semaste                    }
952254721Semaste                    break;
953254721Semaste
954254721Semaste                case 'W':
955254721Semaste                case 'X':
956254721Semaste                    // process exited
957254721Semaste                    state = eStateExited;
958254721Semaste                    break;
959254721Semaste
960254721Semaste                case 'O':
961254721Semaste                    // STDOUT
962254721Semaste                    {
963254721Semaste                        got_async_packet = true;
964254721Semaste                        std::string inferior_stdout;
965254721Semaste                        inferior_stdout.reserve(response.GetBytesLeft () / 2);
966254721Semaste                        char ch;
967254721Semaste                        while ((ch = response.GetHexU8()) != '\0')
968254721Semaste                            inferior_stdout.append(1, ch);
969254721Semaste                        process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
970254721Semaste                    }
971254721Semaste                    break;
972254721Semaste
973254721Semaste                case 'A':
974254721Semaste                    // Async miscellaneous reply. Right now, only profile data is coming through this channel.
975254721Semaste                    {
976254721Semaste                        got_async_packet = true;
977254721Semaste                        std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
978254721Semaste                        if (m_partial_profile_data.length() > 0)
979254721Semaste                        {
980254721Semaste                            m_partial_profile_data.append(input);
981254721Semaste                            input = m_partial_profile_data;
982254721Semaste                            m_partial_profile_data.clear();
983254721Semaste                        }
984254721Semaste
985254721Semaste                        size_t found, pos = 0, len = input.length();
986254721Semaste                        while ((found = input.find(end_delimiter, pos)) != std::string::npos)
987254721Semaste                        {
988254721Semaste                            StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
989254721Semaste                            std::string profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
990254721Semaste                            process->BroadcastAsyncProfileData (profile_data);
991254721Semaste
992254721Semaste                            pos = found + end_delimiter_len;
993254721Semaste                        }
994254721Semaste
995254721Semaste                        if (pos < len)
996254721Semaste                        {
997254721Semaste                            // Last incomplete chunk.
998254721Semaste                            m_partial_profile_data = input.substr(pos);
999254721Semaste                        }
1000254721Semaste                    }
1001254721Semaste                    break;
1002254721Semaste
1003254721Semaste                case 'E':
1004254721Semaste                    // ERROR
1005254721Semaste                    state = eStateInvalid;
1006254721Semaste                    break;
1007254721Semaste
1008254721Semaste                default:
1009254721Semaste                    if (log)
1010254721Semaste                        log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
1011254721Semaste                    state = eStateInvalid;
1012254721Semaste                    break;
1013254721Semaste                }
1014254721Semaste            }
1015254721Semaste        }
1016254721Semaste        else
1017254721Semaste        {
1018254721Semaste            if (log)
1019254721Semaste                log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
1020254721Semaste            state = eStateInvalid;
1021254721Semaste        }
1022254721Semaste    }
1023254721Semaste    if (log)
1024254721Semaste        log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
1025254721Semaste    response.SetFilePos(0);
1026254721Semaste    m_private_is_running.SetValue (false, eBroadcastAlways);
1027254721Semaste    m_public_is_running.SetValue (false, eBroadcastAlways);
1028254721Semaste    return state;
1029254721Semaste}
1030254721Semaste
1031254721Semastebool
1032254721SemasteGDBRemoteCommunicationClient::SendAsyncSignal (int signo)
1033254721Semaste{
1034254721Semaste    Mutex::Locker async_locker (m_async_mutex);
1035254721Semaste    m_async_signal = signo;
1036254721Semaste    bool timed_out = false;
1037254721Semaste    Mutex::Locker locker;
1038254721Semaste    if (SendInterrupt (locker, 1, timed_out))
1039254721Semaste        return true;
1040254721Semaste    m_async_signal = -1;
1041254721Semaste    return false;
1042254721Semaste}
1043254721Semaste
1044254721Semaste// This function takes a mutex locker as a parameter in case the GetSequenceMutex
1045254721Semaste// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
1046254721Semaste// (the expected result), then it will send the halt packet. If it does succeed
1047254721Semaste// then the caller that requested the interrupt will want to keep the sequence
1048254721Semaste// locked down so that no one else can send packets while the caller has control.
1049254721Semaste// This function usually gets called when we are running and need to stop the
1050254721Semaste// target. It can also be used when we are running and and we need to do something
1051254721Semaste// else (like read/write memory), so we need to interrupt the running process
1052254721Semaste// (gdb remote protocol requires this), and do what we need to do, then resume.
1053254721Semaste
1054254721Semastebool
1055254721SemasteGDBRemoteCommunicationClient::SendInterrupt
1056254721Semaste(
1057254721Semaste    Mutex::Locker& locker,
1058254721Semaste    uint32_t seconds_to_wait_for_stop,
1059254721Semaste    bool &timed_out
1060254721Semaste)
1061254721Semaste{
1062254721Semaste    timed_out = false;
1063254721Semaste    Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
1064254721Semaste
1065254721Semaste    if (IsRunning())
1066254721Semaste    {
1067254721Semaste        // Only send an interrupt if our debugserver is running...
1068254721Semaste        if (GetSequenceMutex (locker))
1069254721Semaste        {
1070254721Semaste            if (log)
1071254721Semaste                log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt");
1072254721Semaste        }
1073254721Semaste        else
1074254721Semaste        {
1075254721Semaste            // Someone has the mutex locked waiting for a response or for the
1076254721Semaste            // inferior to stop, so send the interrupt on the down low...
1077254721Semaste            char ctrl_c = '\x03';
1078254721Semaste            ConnectionStatus status = eConnectionStatusSuccess;
1079254721Semaste            size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
1080254721Semaste            if (log)
1081254721Semaste                log->PutCString("send packet: \\x03");
1082254721Semaste            if (bytes_written > 0)
1083254721Semaste            {
1084254721Semaste                m_interrupt_sent = true;
1085254721Semaste                if (seconds_to_wait_for_stop)
1086254721Semaste                {
1087254721Semaste                    TimeValue timeout;
1088254721Semaste                    if (seconds_to_wait_for_stop)
1089254721Semaste                    {
1090254721Semaste                        timeout = TimeValue::Now();
1091254721Semaste                        timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
1092254721Semaste                    }
1093254721Semaste                    if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
1094254721Semaste                    {
1095254721Semaste                        if (log)
1096254721Semaste                            log->PutCString ("SendInterrupt () - sent interrupt, private state stopped");
1097254721Semaste                        return true;
1098254721Semaste                    }
1099254721Semaste                    else
1100254721Semaste                    {
1101254721Semaste                        if (log)
1102254721Semaste                            log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume");
1103254721Semaste                    }
1104254721Semaste                }
1105254721Semaste                else
1106254721Semaste                {
1107254721Semaste                    if (log)
1108254721Semaste                        log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop...");
1109254721Semaste                    return true;
1110254721Semaste                }
1111254721Semaste            }
1112254721Semaste            else
1113254721Semaste            {
1114254721Semaste                if (log)
1115254721Semaste                    log->Printf ("SendInterrupt () - failed to write interrupt");
1116254721Semaste            }
1117254721Semaste            return false;
1118254721Semaste        }
1119254721Semaste    }
1120254721Semaste    else
1121254721Semaste    {
1122254721Semaste        if (log)
1123254721Semaste            log->Printf ("SendInterrupt () - not running");
1124254721Semaste    }
1125254721Semaste    return true;
1126254721Semaste}
1127254721Semaste
1128254721Semastelldb::pid_t
1129254721SemasteGDBRemoteCommunicationClient::GetCurrentProcessID ()
1130254721Semaste{
1131254721Semaste    StringExtractorGDBRemote response;
1132269024Semaste    if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false) == PacketResult::Success)
1133254721Semaste    {
1134254721Semaste        if (response.GetChar() == 'Q')
1135254721Semaste            if (response.GetChar() == 'C')
1136254721Semaste                return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
1137254721Semaste    }
1138254721Semaste    return LLDB_INVALID_PROCESS_ID;
1139254721Semaste}
1140254721Semaste
1141254721Semastebool
1142254721SemasteGDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
1143254721Semaste{
1144254721Semaste    error_str.clear();
1145254721Semaste    StringExtractorGDBRemote response;
1146269024Semaste    if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false) == PacketResult::Success)
1147254721Semaste    {
1148254721Semaste        if (response.IsOKResponse())
1149254721Semaste            return true;
1150254721Semaste        if (response.GetChar() == 'E')
1151254721Semaste        {
1152254721Semaste            // A string the describes what failed when launching...
1153254721Semaste            error_str = response.GetStringRef().substr(1);
1154254721Semaste        }
1155254721Semaste        else
1156254721Semaste        {
1157254721Semaste            error_str.assign ("unknown error occurred launching process");
1158254721Semaste        }
1159254721Semaste    }
1160254721Semaste    else
1161254721Semaste    {
1162254721Semaste        error_str.assign ("timed out waiting for app to launch");
1163254721Semaste    }
1164254721Semaste    return false;
1165254721Semaste}
1166254721Semaste
1167254721Semasteint
1168263367SemasteGDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info)
1169254721Semaste{
1170263367Semaste    // Since we don't get the send argv0 separate from the executable path, we need to
1171263367Semaste    // make sure to use the actual exectuable path found in the launch_info...
1172263367Semaste    std::vector<const char *> argv;
1173263367Semaste    FileSpec exe_file = launch_info.GetExecutableFile();
1174263367Semaste    std::string exe_path;
1175263367Semaste    const char *arg = NULL;
1176263367Semaste    const Args &launch_args = launch_info.GetArguments();
1177263367Semaste    if (exe_file)
1178263367Semaste        exe_path = exe_file.GetPath();
1179263367Semaste    else
1180254721Semaste    {
1181263367Semaste        arg = launch_args.GetArgumentAtIndex(0);
1182263367Semaste        if (arg)
1183263367Semaste            exe_path = arg;
1184263367Semaste    }
1185263367Semaste    if (!exe_path.empty())
1186263367Semaste    {
1187263367Semaste        argv.push_back(exe_path.c_str());
1188263367Semaste        for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i)
1189263367Semaste        {
1190263367Semaste            if (arg)
1191263367Semaste                argv.push_back(arg);
1192263367Semaste        }
1193263367Semaste    }
1194263367Semaste    if (!argv.empty())
1195263367Semaste    {
1196254721Semaste        StreamString packet;
1197254721Semaste        packet.PutChar('A');
1198263367Semaste        for (size_t i = 0, n = argv.size(); i < n; ++i)
1199254721Semaste        {
1200263367Semaste            arg = argv[i];
1201254721Semaste            const int arg_len = strlen(arg);
1202254721Semaste            if (i > 0)
1203254721Semaste                packet.PutChar(',');
1204263367Semaste            packet.Printf("%i,%i,", arg_len * 2, (int)i);
1205254721Semaste            packet.PutBytesAsRawHex8 (arg, arg_len);
1206254721Semaste        }
1207254721Semaste
1208254721Semaste        StringExtractorGDBRemote response;
1209269024Semaste        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1210254721Semaste        {
1211254721Semaste            if (response.IsOKResponse())
1212254721Semaste                return 0;
1213254721Semaste            uint8_t error = response.GetError();
1214254721Semaste            if (error)
1215254721Semaste                return error;
1216254721Semaste        }
1217254721Semaste    }
1218254721Semaste    return -1;
1219254721Semaste}
1220254721Semaste
1221254721Semasteint
1222254721SemasteGDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
1223254721Semaste{
1224254721Semaste    if (name_equal_value && name_equal_value[0])
1225254721Semaste    {
1226254721Semaste        StreamString packet;
1227263363Semaste        bool send_hex_encoding = false;
1228263363Semaste        for (const char *p = name_equal_value; *p != '\0' && send_hex_encoding == false; ++p)
1229263363Semaste        {
1230263363Semaste            if (isprint(*p))
1231263363Semaste            {
1232263363Semaste                switch (*p)
1233263363Semaste                {
1234263363Semaste                    case '$':
1235263363Semaste                    case '#':
1236263363Semaste                        send_hex_encoding = true;
1237263363Semaste                        break;
1238263363Semaste                    default:
1239263363Semaste                        break;
1240263363Semaste                }
1241263363Semaste            }
1242263363Semaste            else
1243263363Semaste            {
1244263363Semaste                // We have non printable characters, lets hex encode this...
1245263363Semaste                send_hex_encoding = true;
1246263363Semaste            }
1247263363Semaste        }
1248263363Semaste
1249254721Semaste        StringExtractorGDBRemote response;
1250263363Semaste        if (send_hex_encoding)
1251254721Semaste        {
1252263363Semaste            if (m_supports_QEnvironmentHexEncoded)
1253263363Semaste            {
1254263363Semaste                packet.PutCString("QEnvironmentHexEncoded:");
1255263363Semaste                packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value));
1256269024Semaste                if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1257263363Semaste                {
1258263363Semaste                    if (response.IsOKResponse())
1259263363Semaste                        return 0;
1260263363Semaste                    uint8_t error = response.GetError();
1261263363Semaste                    if (error)
1262263363Semaste                        return error;
1263263363Semaste                    if (response.IsUnsupportedResponse())
1264263363Semaste                        m_supports_QEnvironmentHexEncoded = false;
1265263363Semaste                }
1266263363Semaste            }
1267263363Semaste
1268254721Semaste        }
1269263363Semaste        else if (m_supports_QEnvironment)
1270263363Semaste        {
1271263363Semaste            packet.Printf("QEnvironment:%s", name_equal_value);
1272269024Semaste            if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1273263363Semaste            {
1274263363Semaste                if (response.IsOKResponse())
1275263363Semaste                    return 0;
1276263363Semaste                uint8_t error = response.GetError();
1277263363Semaste                if (error)
1278263363Semaste                    return error;
1279263363Semaste                if (response.IsUnsupportedResponse())
1280263363Semaste                    m_supports_QEnvironment = false;
1281263363Semaste            }
1282263363Semaste        }
1283254721Semaste    }
1284254721Semaste    return -1;
1285254721Semaste}
1286254721Semaste
1287254721Semasteint
1288254721SemasteGDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
1289254721Semaste{
1290254721Semaste    if (arch && arch[0])
1291254721Semaste    {
1292254721Semaste        StreamString packet;
1293254721Semaste        packet.Printf("QLaunchArch:%s", arch);
1294254721Semaste        StringExtractorGDBRemote response;
1295269024Semaste        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1296254721Semaste        {
1297254721Semaste            if (response.IsOKResponse())
1298254721Semaste                return 0;
1299254721Semaste            uint8_t error = response.GetError();
1300254721Semaste            if (error)
1301254721Semaste                return error;
1302254721Semaste        }
1303254721Semaste    }
1304254721Semaste    return -1;
1305254721Semaste}
1306254721Semaste
1307254721Semastebool
1308254721SemasteGDBRemoteCommunicationClient::GetOSVersion (uint32_t &major,
1309254721Semaste                                            uint32_t &minor,
1310254721Semaste                                            uint32_t &update)
1311254721Semaste{
1312254721Semaste    if (GetHostInfo ())
1313254721Semaste    {
1314254721Semaste        if (m_os_version_major != UINT32_MAX)
1315254721Semaste        {
1316254721Semaste            major = m_os_version_major;
1317254721Semaste            minor = m_os_version_minor;
1318254721Semaste            update = m_os_version_update;
1319254721Semaste            return true;
1320254721Semaste        }
1321254721Semaste    }
1322254721Semaste    return false;
1323254721Semaste}
1324254721Semaste
1325254721Semastebool
1326254721SemasteGDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
1327254721Semaste{
1328254721Semaste    if (GetHostInfo ())
1329254721Semaste    {
1330254721Semaste        if (!m_os_build.empty())
1331254721Semaste        {
1332254721Semaste            s = m_os_build;
1333254721Semaste            return true;
1334254721Semaste        }
1335254721Semaste    }
1336254721Semaste    s.clear();
1337254721Semaste    return false;
1338254721Semaste}
1339254721Semaste
1340254721Semaste
1341254721Semastebool
1342254721SemasteGDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
1343254721Semaste{
1344254721Semaste    if (GetHostInfo ())
1345254721Semaste    {
1346254721Semaste        if (!m_os_kernel.empty())
1347254721Semaste        {
1348254721Semaste            s = m_os_kernel;
1349254721Semaste            return true;
1350254721Semaste        }
1351254721Semaste    }
1352254721Semaste    s.clear();
1353254721Semaste    return false;
1354254721Semaste}
1355254721Semaste
1356254721Semastebool
1357254721SemasteGDBRemoteCommunicationClient::GetHostname (std::string &s)
1358254721Semaste{
1359254721Semaste    if (GetHostInfo ())
1360254721Semaste    {
1361254721Semaste        if (!m_hostname.empty())
1362254721Semaste        {
1363254721Semaste            s = m_hostname;
1364254721Semaste            return true;
1365254721Semaste        }
1366254721Semaste    }
1367254721Semaste    s.clear();
1368254721Semaste    return false;
1369254721Semaste}
1370254721Semaste
1371254721SemasteArchSpec
1372254721SemasteGDBRemoteCommunicationClient::GetSystemArchitecture ()
1373254721Semaste{
1374254721Semaste    if (GetHostInfo ())
1375254721Semaste        return m_host_arch;
1376254721Semaste    return ArchSpec();
1377254721Semaste}
1378254721Semaste
1379254721Semasteconst lldb_private::ArchSpec &
1380254721SemasteGDBRemoteCommunicationClient::GetProcessArchitecture ()
1381254721Semaste{
1382254721Semaste    if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
1383254721Semaste        GetCurrentProcessInfo ();
1384254721Semaste    return m_process_arch;
1385254721Semaste}
1386254721Semaste
1387254721Semaste
1388254721Semastebool
1389254721SemasteGDBRemoteCommunicationClient::GetHostInfo (bool force)
1390254721Semaste{
1391254721Semaste    if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
1392254721Semaste    {
1393254721Semaste        m_qHostInfo_is_valid = eLazyBoolNo;
1394254721Semaste        StringExtractorGDBRemote response;
1395269024Semaste        if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success)
1396254721Semaste        {
1397254721Semaste            if (response.IsNormalResponse())
1398254721Semaste            {
1399254721Semaste                std::string name;
1400254721Semaste                std::string value;
1401254721Semaste                uint32_t cpu = LLDB_INVALID_CPUTYPE;
1402254721Semaste                uint32_t sub = 0;
1403254721Semaste                std::string arch_name;
1404254721Semaste                std::string os_name;
1405254721Semaste                std::string vendor_name;
1406254721Semaste                std::string triple;
1407269024Semaste                std::string distribution_id;
1408254721Semaste                uint32_t pointer_byte_size = 0;
1409254721Semaste                StringExtractor extractor;
1410254721Semaste                ByteOrder byte_order = eByteOrderInvalid;
1411254721Semaste                uint32_t num_keys_decoded = 0;
1412254721Semaste                while (response.GetNameColonValue(name, value))
1413254721Semaste                {
1414254721Semaste                    if (name.compare("cputype") == 0)
1415254721Semaste                    {
1416254721Semaste                        // exception type in big endian hex
1417254721Semaste                        cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
1418254721Semaste                        if (cpu != LLDB_INVALID_CPUTYPE)
1419254721Semaste                            ++num_keys_decoded;
1420254721Semaste                    }
1421254721Semaste                    else if (name.compare("cpusubtype") == 0)
1422254721Semaste                    {
1423254721Semaste                        // exception count in big endian hex
1424254721Semaste                        sub = Args::StringToUInt32 (value.c_str(), 0, 0);
1425254721Semaste                        if (sub != 0)
1426254721Semaste                            ++num_keys_decoded;
1427254721Semaste                    }
1428254721Semaste                    else if (name.compare("arch") == 0)
1429254721Semaste                    {
1430254721Semaste                        arch_name.swap (value);
1431254721Semaste                        ++num_keys_decoded;
1432254721Semaste                    }
1433254721Semaste                    else if (name.compare("triple") == 0)
1434254721Semaste                    {
1435254721Semaste                        // The triple comes as ASCII hex bytes since it contains '-' chars
1436254721Semaste                        extractor.GetStringRef().swap(value);
1437254721Semaste                        extractor.SetFilePos(0);
1438254721Semaste                        extractor.GetHexByteString (triple);
1439254721Semaste                        ++num_keys_decoded;
1440254721Semaste                    }
1441269024Semaste                    else if (name.compare ("distribution_id") == 0)
1442269024Semaste                    {
1443269024Semaste                        extractor.GetStringRef ().swap (value);
1444269024Semaste                        extractor.SetFilePos (0);
1445269024Semaste                        extractor.GetHexByteString (distribution_id);
1446269024Semaste                        ++num_keys_decoded;
1447269024Semaste                    }
1448254721Semaste                    else if (name.compare("os_build") == 0)
1449254721Semaste                    {
1450254721Semaste                        extractor.GetStringRef().swap(value);
1451254721Semaste                        extractor.SetFilePos(0);
1452254721Semaste                        extractor.GetHexByteString (m_os_build);
1453254721Semaste                        ++num_keys_decoded;
1454254721Semaste                    }
1455254721Semaste                    else if (name.compare("hostname") == 0)
1456254721Semaste                    {
1457254721Semaste                        extractor.GetStringRef().swap(value);
1458254721Semaste                        extractor.SetFilePos(0);
1459254721Semaste                        extractor.GetHexByteString (m_hostname);
1460254721Semaste                        ++num_keys_decoded;
1461254721Semaste                    }
1462254721Semaste                    else if (name.compare("os_kernel") == 0)
1463254721Semaste                    {
1464254721Semaste                        extractor.GetStringRef().swap(value);
1465254721Semaste                        extractor.SetFilePos(0);
1466254721Semaste                        extractor.GetHexByteString (m_os_kernel);
1467254721Semaste                        ++num_keys_decoded;
1468254721Semaste                    }
1469254721Semaste                    else if (name.compare("ostype") == 0)
1470254721Semaste                    {
1471254721Semaste                        os_name.swap (value);
1472254721Semaste                        ++num_keys_decoded;
1473254721Semaste                    }
1474254721Semaste                    else if (name.compare("vendor") == 0)
1475254721Semaste                    {
1476254721Semaste                        vendor_name.swap(value);
1477254721Semaste                        ++num_keys_decoded;
1478254721Semaste                    }
1479254721Semaste                    else if (name.compare("endian") == 0)
1480254721Semaste                    {
1481254721Semaste                        ++num_keys_decoded;
1482254721Semaste                        if (value.compare("little") == 0)
1483254721Semaste                            byte_order = eByteOrderLittle;
1484254721Semaste                        else if (value.compare("big") == 0)
1485254721Semaste                            byte_order = eByteOrderBig;
1486254721Semaste                        else if (value.compare("pdp") == 0)
1487254721Semaste                            byte_order = eByteOrderPDP;
1488254721Semaste                        else
1489254721Semaste                            --num_keys_decoded;
1490254721Semaste                    }
1491254721Semaste                    else if (name.compare("ptrsize") == 0)
1492254721Semaste                    {
1493254721Semaste                        pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
1494254721Semaste                        if (pointer_byte_size != 0)
1495254721Semaste                            ++num_keys_decoded;
1496254721Semaste                    }
1497254721Semaste                    else if (name.compare("os_version") == 0)
1498254721Semaste                    {
1499254721Semaste                        Args::StringToVersion (value.c_str(),
1500254721Semaste                                               m_os_version_major,
1501254721Semaste                                               m_os_version_minor,
1502254721Semaste                                               m_os_version_update);
1503254721Semaste                        if (m_os_version_major != UINT32_MAX)
1504254721Semaste                            ++num_keys_decoded;
1505254721Semaste                    }
1506254721Semaste                    else if (name.compare("watchpoint_exceptions_received") == 0)
1507254721Semaste                    {
1508254721Semaste                        ++num_keys_decoded;
1509254721Semaste                        if (strcmp(value.c_str(),"before") == 0)
1510254721Semaste                            m_watchpoints_trigger_after_instruction = eLazyBoolNo;
1511254721Semaste                        else if (strcmp(value.c_str(),"after") == 0)
1512254721Semaste                            m_watchpoints_trigger_after_instruction = eLazyBoolYes;
1513254721Semaste                        else
1514254721Semaste                            --num_keys_decoded;
1515254721Semaste                    }
1516263363Semaste                    else if (name.compare("default_packet_timeout") == 0)
1517263363Semaste                    {
1518263363Semaste                        m_default_packet_timeout = Args::StringToUInt32(value.c_str(), 0);
1519263363Semaste                        if (m_default_packet_timeout > 0)
1520263363Semaste                        {
1521263363Semaste                            SetPacketTimeout(m_default_packet_timeout);
1522263363Semaste                            ++num_keys_decoded;
1523263363Semaste                        }
1524263363Semaste                    }
1525254721Semaste
1526254721Semaste                }
1527254721Semaste
1528254721Semaste                if (num_keys_decoded > 0)
1529254721Semaste                    m_qHostInfo_is_valid = eLazyBoolYes;
1530254721Semaste
1531254721Semaste                if (triple.empty())
1532254721Semaste                {
1533254721Semaste                    if (arch_name.empty())
1534254721Semaste                    {
1535254721Semaste                        if (cpu != LLDB_INVALID_CPUTYPE)
1536254721Semaste                        {
1537254721Semaste                            m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
1538254721Semaste                            if (pointer_byte_size)
1539254721Semaste                            {
1540254721Semaste                                assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1541254721Semaste                            }
1542254721Semaste                            if (byte_order != eByteOrderInvalid)
1543254721Semaste                            {
1544254721Semaste                                assert (byte_order == m_host_arch.GetByteOrder());
1545254721Semaste                            }
1546254721Semaste
1547254721Semaste                            if (!os_name.empty() && vendor_name.compare("apple") == 0 && os_name.find("darwin") == 0)
1548254721Semaste                            {
1549254721Semaste                                switch (m_host_arch.GetMachine())
1550254721Semaste                                {
1551254721Semaste                                case llvm::Triple::arm:
1552254721Semaste                                case llvm::Triple::thumb:
1553254721Semaste                                    os_name = "ios";
1554254721Semaste                                    break;
1555254721Semaste                                default:
1556254721Semaste                                    os_name = "macosx";
1557254721Semaste                                    break;
1558254721Semaste                                }
1559254721Semaste                            }
1560254721Semaste                            if (!vendor_name.empty())
1561254721Semaste                                m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
1562254721Semaste                            if (!os_name.empty())
1563254721Semaste                                m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
1564254721Semaste
1565254721Semaste                        }
1566254721Semaste                    }
1567254721Semaste                    else
1568254721Semaste                    {
1569254721Semaste                        std::string triple;
1570254721Semaste                        triple += arch_name;
1571254721Semaste                        if (!vendor_name.empty() || !os_name.empty())
1572254721Semaste                        {
1573254721Semaste                            triple += '-';
1574254721Semaste                            if (vendor_name.empty())
1575254721Semaste                                triple += "unknown";
1576254721Semaste                            else
1577254721Semaste                                triple += vendor_name;
1578254721Semaste                            triple += '-';
1579254721Semaste                            if (os_name.empty())
1580254721Semaste                                triple += "unknown";
1581254721Semaste                            else
1582254721Semaste                                triple += os_name;
1583254721Semaste                        }
1584254721Semaste                        m_host_arch.SetTriple (triple.c_str());
1585254721Semaste
1586254721Semaste                        llvm::Triple &host_triple = m_host_arch.GetTriple();
1587254721Semaste                        if (host_triple.getVendor() == llvm::Triple::Apple && host_triple.getOS() == llvm::Triple::Darwin)
1588254721Semaste                        {
1589254721Semaste                            switch (m_host_arch.GetMachine())
1590254721Semaste                            {
1591254721Semaste                                case llvm::Triple::arm:
1592254721Semaste                                case llvm::Triple::thumb:
1593254721Semaste                                    host_triple.setOS(llvm::Triple::IOS);
1594254721Semaste                                    break;
1595254721Semaste                                default:
1596254721Semaste                                    host_triple.setOS(llvm::Triple::MacOSX);
1597254721Semaste                                    break;
1598254721Semaste                            }
1599254721Semaste                        }
1600254721Semaste                        if (pointer_byte_size)
1601254721Semaste                        {
1602254721Semaste                            assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1603254721Semaste                        }
1604254721Semaste                        if (byte_order != eByteOrderInvalid)
1605254721Semaste                        {
1606254721Semaste                            assert (byte_order == m_host_arch.GetByteOrder());
1607254721Semaste                        }
1608254721Semaste
1609254721Semaste                    }
1610254721Semaste                }
1611254721Semaste                else
1612254721Semaste                {
1613254721Semaste                    m_host_arch.SetTriple (triple.c_str());
1614254721Semaste                    if (pointer_byte_size)
1615254721Semaste                    {
1616254721Semaste                        assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
1617254721Semaste                    }
1618254721Semaste                    if (byte_order != eByteOrderInvalid)
1619254721Semaste                    {
1620254721Semaste                        assert (byte_order == m_host_arch.GetByteOrder());
1621254721Semaste                    }
1622269024Semaste                }
1623269024Semaste                if (!distribution_id.empty ())
1624269024Semaste                    m_host_arch.SetDistributionId (distribution_id.c_str ());
1625254721Semaste            }
1626254721Semaste        }
1627254721Semaste    }
1628254721Semaste    return m_qHostInfo_is_valid == eLazyBoolYes;
1629254721Semaste}
1630254721Semaste
1631254721Semasteint
1632254721SemasteGDBRemoteCommunicationClient::SendAttach
1633254721Semaste(
1634254721Semaste    lldb::pid_t pid,
1635254721Semaste    StringExtractorGDBRemote& response
1636254721Semaste)
1637254721Semaste{
1638254721Semaste    if (pid != LLDB_INVALID_PROCESS_ID)
1639254721Semaste    {
1640254721Semaste        char packet[64];
1641254721Semaste        const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
1642254721Semaste        assert (packet_len < (int)sizeof(packet));
1643269024Semaste        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
1644254721Semaste        {
1645254721Semaste            if (response.IsErrorResponse())
1646254721Semaste                return response.GetError();
1647254721Semaste            return 0;
1648254721Semaste        }
1649254721Semaste    }
1650254721Semaste    return -1;
1651254721Semaste}
1652254721Semaste
1653254721Semasteconst lldb_private::ArchSpec &
1654254721SemasteGDBRemoteCommunicationClient::GetHostArchitecture ()
1655254721Semaste{
1656254721Semaste    if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1657254721Semaste        GetHostInfo ();
1658254721Semaste    return m_host_arch;
1659254721Semaste}
1660254721Semaste
1661263363Semasteuint32_t
1662263363SemasteGDBRemoteCommunicationClient::GetHostDefaultPacketTimeout ()
1663263363Semaste{
1664263363Semaste    if (m_qHostInfo_is_valid == eLazyBoolCalculate)
1665263363Semaste        GetHostInfo ();
1666263363Semaste    return m_default_packet_timeout;
1667263363Semaste}
1668263363Semaste
1669254721Semasteaddr_t
1670254721SemasteGDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
1671254721Semaste{
1672254721Semaste    if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
1673254721Semaste    {
1674254721Semaste        m_supports_alloc_dealloc_memory = eLazyBoolYes;
1675254721Semaste        char packet[64];
1676254721Semaste        const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
1677254721Semaste                                           (uint64_t)size,
1678254721Semaste                                           permissions & lldb::ePermissionsReadable ? "r" : "",
1679254721Semaste                                           permissions & lldb::ePermissionsWritable ? "w" : "",
1680254721Semaste                                           permissions & lldb::ePermissionsExecutable ? "x" : "");
1681254721Semaste        assert (packet_len < (int)sizeof(packet));
1682254721Semaste        StringExtractorGDBRemote response;
1683269024Semaste        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
1684254721Semaste        {
1685254721Semaste            if (!response.IsErrorResponse())
1686254721Semaste                return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
1687254721Semaste        }
1688254721Semaste        else
1689254721Semaste        {
1690254721Semaste            m_supports_alloc_dealloc_memory = eLazyBoolNo;
1691254721Semaste        }
1692254721Semaste    }
1693254721Semaste    return LLDB_INVALID_ADDRESS;
1694254721Semaste}
1695254721Semaste
1696254721Semastebool
1697254721SemasteGDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
1698254721Semaste{
1699254721Semaste    if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
1700254721Semaste    {
1701254721Semaste        m_supports_alloc_dealloc_memory = eLazyBoolYes;
1702254721Semaste        char packet[64];
1703254721Semaste        const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
1704254721Semaste        assert (packet_len < (int)sizeof(packet));
1705254721Semaste        StringExtractorGDBRemote response;
1706269024Semaste        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
1707254721Semaste        {
1708254721Semaste            if (response.IsOKResponse())
1709254721Semaste                return true;
1710254721Semaste        }
1711254721Semaste        else
1712254721Semaste        {
1713254721Semaste            m_supports_alloc_dealloc_memory = eLazyBoolNo;
1714254721Semaste        }
1715254721Semaste    }
1716254721Semaste    return false;
1717254721Semaste}
1718254721Semaste
1719254721SemasteError
1720254721SemasteGDBRemoteCommunicationClient::Detach (bool keep_stopped)
1721254721Semaste{
1722254721Semaste    Error error;
1723254721Semaste
1724254721Semaste    if (keep_stopped)
1725254721Semaste    {
1726254721Semaste        if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
1727254721Semaste        {
1728254721Semaste            char packet[64];
1729254721Semaste            const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
1730254721Semaste            assert (packet_len < (int)sizeof(packet));
1731254721Semaste            StringExtractorGDBRemote response;
1732269024Semaste            if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
1733254721Semaste            {
1734254721Semaste                m_supports_detach_stay_stopped = eLazyBoolYes;
1735254721Semaste            }
1736254721Semaste            else
1737254721Semaste            {
1738254721Semaste                m_supports_detach_stay_stopped = eLazyBoolNo;
1739254721Semaste            }
1740254721Semaste        }
1741254721Semaste
1742254721Semaste        if (m_supports_detach_stay_stopped == eLazyBoolNo)
1743254721Semaste        {
1744254721Semaste            error.SetErrorString("Stays stopped not supported by this target.");
1745254721Semaste            return error;
1746254721Semaste        }
1747254721Semaste        else
1748254721Semaste        {
1749269024Semaste            PacketResult packet_result = SendPacket ("D1", 2);
1750269024Semaste            if (packet_result != PacketResult::Success)
1751254721Semaste                error.SetErrorString ("Sending extended disconnect packet failed.");
1752254721Semaste        }
1753254721Semaste    }
1754254721Semaste    else
1755254721Semaste    {
1756269024Semaste        PacketResult packet_result = SendPacket ("D", 1);
1757269024Semaste        if (packet_result != PacketResult::Success)
1758254721Semaste            error.SetErrorString ("Sending disconnect packet failed.");
1759254721Semaste    }
1760254721Semaste    return error;
1761254721Semaste}
1762254721Semaste
1763254721SemasteError
1764254721SemasteGDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
1765254721Semaste                                                  lldb_private::MemoryRegionInfo &region_info)
1766254721Semaste{
1767254721Semaste    Error error;
1768254721Semaste    region_info.Clear();
1769254721Semaste
1770254721Semaste    if (m_supports_memory_region_info != eLazyBoolNo)
1771254721Semaste    {
1772254721Semaste        m_supports_memory_region_info = eLazyBoolYes;
1773254721Semaste        char packet[64];
1774254721Semaste        const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
1775254721Semaste        assert (packet_len < (int)sizeof(packet));
1776254721Semaste        StringExtractorGDBRemote response;
1777269024Semaste        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
1778254721Semaste        {
1779254721Semaste            std::string name;
1780254721Semaste            std::string value;
1781254721Semaste            addr_t addr_value;
1782254721Semaste            bool success = true;
1783254721Semaste            bool saw_permissions = false;
1784254721Semaste            while (success && response.GetNameColonValue(name, value))
1785254721Semaste            {
1786254721Semaste                if (name.compare ("start") == 0)
1787254721Semaste                {
1788254721Semaste                    addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
1789254721Semaste                    if (success)
1790254721Semaste                        region_info.GetRange().SetRangeBase(addr_value);
1791254721Semaste                }
1792254721Semaste                else if (name.compare ("size") == 0)
1793254721Semaste                {
1794254721Semaste                    addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success);
1795254721Semaste                    if (success)
1796254721Semaste                        region_info.GetRange().SetByteSize (addr_value);
1797254721Semaste                }
1798254721Semaste                else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
1799254721Semaste                {
1800254721Semaste                    saw_permissions = true;
1801254721Semaste                    if (region_info.GetRange().Contains (addr))
1802254721Semaste                    {
1803254721Semaste                        if (value.find('r') != std::string::npos)
1804254721Semaste                            region_info.SetReadable (MemoryRegionInfo::eYes);
1805254721Semaste                        else
1806254721Semaste                            region_info.SetReadable (MemoryRegionInfo::eNo);
1807254721Semaste
1808254721Semaste                        if (value.find('w') != std::string::npos)
1809254721Semaste                            region_info.SetWritable (MemoryRegionInfo::eYes);
1810254721Semaste                        else
1811254721Semaste                            region_info.SetWritable (MemoryRegionInfo::eNo);
1812254721Semaste
1813254721Semaste                        if (value.find('x') != std::string::npos)
1814254721Semaste                            region_info.SetExecutable (MemoryRegionInfo::eYes);
1815254721Semaste                        else
1816254721Semaste                            region_info.SetExecutable (MemoryRegionInfo::eNo);
1817254721Semaste                    }
1818254721Semaste                    else
1819254721Semaste                    {
1820254721Semaste                        // The reported region does not contain this address -- we're looking at an unmapped page
1821254721Semaste                        region_info.SetReadable (MemoryRegionInfo::eNo);
1822254721Semaste                        region_info.SetWritable (MemoryRegionInfo::eNo);
1823254721Semaste                        region_info.SetExecutable (MemoryRegionInfo::eNo);
1824254721Semaste                    }
1825254721Semaste                }
1826254721Semaste                else if (name.compare ("error") == 0)
1827254721Semaste                {
1828254721Semaste                    StringExtractorGDBRemote name_extractor;
1829254721Semaste                    // Swap "value" over into "name_extractor"
1830254721Semaste                    name_extractor.GetStringRef().swap(value);
1831254721Semaste                    // Now convert the HEX bytes into a string value
1832254721Semaste                    name_extractor.GetHexByteString (value);
1833254721Semaste                    error.SetErrorString(value.c_str());
1834254721Semaste                }
1835254721Semaste            }
1836254721Semaste
1837254721Semaste            // We got a valid address range back but no permissions -- which means this is an unmapped page
1838254721Semaste            if (region_info.GetRange().IsValid() && saw_permissions == false)
1839254721Semaste            {
1840254721Semaste                region_info.SetReadable (MemoryRegionInfo::eNo);
1841254721Semaste                region_info.SetWritable (MemoryRegionInfo::eNo);
1842254721Semaste                region_info.SetExecutable (MemoryRegionInfo::eNo);
1843254721Semaste            }
1844254721Semaste        }
1845254721Semaste        else
1846254721Semaste        {
1847254721Semaste            m_supports_memory_region_info = eLazyBoolNo;
1848254721Semaste        }
1849254721Semaste    }
1850254721Semaste
1851254721Semaste    if (m_supports_memory_region_info == eLazyBoolNo)
1852254721Semaste    {
1853254721Semaste        error.SetErrorString("qMemoryRegionInfo is not supported");
1854254721Semaste    }
1855254721Semaste    if (error.Fail())
1856254721Semaste        region_info.Clear();
1857254721Semaste    return error;
1858254721Semaste
1859254721Semaste}
1860254721Semaste
1861254721SemasteError
1862254721SemasteGDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
1863254721Semaste{
1864254721Semaste    Error error;
1865254721Semaste
1866254721Semaste    if (m_supports_watchpoint_support_info == eLazyBoolYes)
1867254721Semaste    {
1868254721Semaste        num = m_num_supported_hardware_watchpoints;
1869254721Semaste        return error;
1870254721Semaste    }
1871254721Semaste
1872254721Semaste    // Set num to 0 first.
1873254721Semaste    num = 0;
1874254721Semaste    if (m_supports_watchpoint_support_info != eLazyBoolNo)
1875254721Semaste    {
1876254721Semaste        char packet[64];
1877254721Semaste        const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
1878254721Semaste        assert (packet_len < (int)sizeof(packet));
1879254721Semaste        StringExtractorGDBRemote response;
1880269024Semaste        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
1881254721Semaste        {
1882254721Semaste            m_supports_watchpoint_support_info = eLazyBoolYes;
1883254721Semaste            std::string name;
1884254721Semaste            std::string value;
1885254721Semaste            while (response.GetNameColonValue(name, value))
1886254721Semaste            {
1887254721Semaste                if (name.compare ("num") == 0)
1888254721Semaste                {
1889254721Semaste                    num = Args::StringToUInt32(value.c_str(), 0, 0);
1890254721Semaste                    m_num_supported_hardware_watchpoints = num;
1891254721Semaste                }
1892254721Semaste            }
1893254721Semaste        }
1894254721Semaste        else
1895254721Semaste        {
1896254721Semaste            m_supports_watchpoint_support_info = eLazyBoolNo;
1897254721Semaste        }
1898254721Semaste    }
1899254721Semaste
1900254721Semaste    if (m_supports_watchpoint_support_info == eLazyBoolNo)
1901254721Semaste    {
1902254721Semaste        error.SetErrorString("qWatchpointSupportInfo is not supported");
1903254721Semaste    }
1904254721Semaste    return error;
1905254721Semaste
1906254721Semaste}
1907254721Semaste
1908254721Semastelldb_private::Error
1909254721SemasteGDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after)
1910254721Semaste{
1911254721Semaste    Error error(GetWatchpointSupportInfo(num));
1912254721Semaste    if (error.Success())
1913254721Semaste        error = GetWatchpointsTriggerAfterInstruction(after);
1914254721Semaste    return error;
1915254721Semaste}
1916254721Semaste
1917254721Semastelldb_private::Error
1918254721SemasteGDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after)
1919254721Semaste{
1920254721Semaste    Error error;
1921254721Semaste
1922254721Semaste    // we assume watchpoints will happen after running the relevant opcode
1923254721Semaste    // and we only want to override this behavior if we have explicitly
1924254721Semaste    // received a qHostInfo telling us otherwise
1925254721Semaste    if (m_qHostInfo_is_valid != eLazyBoolYes)
1926254721Semaste        after = true;
1927254721Semaste    else
1928254721Semaste        after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
1929254721Semaste    return error;
1930254721Semaste}
1931254721Semaste
1932254721Semasteint
1933254721SemasteGDBRemoteCommunicationClient::SetSTDIN (char const *path)
1934254721Semaste{
1935254721Semaste    if (path && path[0])
1936254721Semaste    {
1937254721Semaste        StreamString packet;
1938254721Semaste        packet.PutCString("QSetSTDIN:");
1939254721Semaste        packet.PutBytesAsRawHex8(path, strlen(path));
1940254721Semaste
1941254721Semaste        StringExtractorGDBRemote response;
1942269024Semaste        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1943254721Semaste        {
1944254721Semaste            if (response.IsOKResponse())
1945254721Semaste                return 0;
1946254721Semaste            uint8_t error = response.GetError();
1947254721Semaste            if (error)
1948254721Semaste                return error;
1949254721Semaste        }
1950254721Semaste    }
1951254721Semaste    return -1;
1952254721Semaste}
1953254721Semaste
1954254721Semasteint
1955254721SemasteGDBRemoteCommunicationClient::SetSTDOUT (char const *path)
1956254721Semaste{
1957254721Semaste    if (path && path[0])
1958254721Semaste    {
1959254721Semaste        StreamString packet;
1960254721Semaste        packet.PutCString("QSetSTDOUT:");
1961254721Semaste        packet.PutBytesAsRawHex8(path, strlen(path));
1962254721Semaste
1963254721Semaste        StringExtractorGDBRemote response;
1964269024Semaste        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1965254721Semaste        {
1966254721Semaste            if (response.IsOKResponse())
1967254721Semaste                return 0;
1968254721Semaste            uint8_t error = response.GetError();
1969254721Semaste            if (error)
1970254721Semaste                return error;
1971254721Semaste        }
1972254721Semaste    }
1973254721Semaste    return -1;
1974254721Semaste}
1975254721Semaste
1976254721Semasteint
1977254721SemasteGDBRemoteCommunicationClient::SetSTDERR (char const *path)
1978254721Semaste{
1979254721Semaste    if (path && path[0])
1980254721Semaste    {
1981254721Semaste        StreamString packet;
1982254721Semaste        packet.PutCString("QSetSTDERR:");
1983254721Semaste        packet.PutBytesAsRawHex8(path, strlen(path));
1984254721Semaste
1985254721Semaste        StringExtractorGDBRemote response;
1986269024Semaste        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
1987254721Semaste        {
1988254721Semaste            if (response.IsOKResponse())
1989254721Semaste                return 0;
1990254721Semaste            uint8_t error = response.GetError();
1991254721Semaste            if (error)
1992254721Semaste                return error;
1993254721Semaste        }
1994254721Semaste    }
1995254721Semaste    return -1;
1996254721Semaste}
1997254721Semaste
1998263367Semastebool
1999263367SemasteGDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd)
2000263367Semaste{
2001263367Semaste    StringExtractorGDBRemote response;
2002269024Semaste    if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success)
2003263367Semaste    {
2004263367Semaste        if (response.IsUnsupportedResponse())
2005263367Semaste            return false;
2006263367Semaste        if (response.IsErrorResponse())
2007263367Semaste            return false;
2008263367Semaste        response.GetHexByteString (cwd);
2009263367Semaste        return !cwd.empty();
2010263367Semaste    }
2011263367Semaste    return false;
2012263367Semaste}
2013263367Semaste
2014254721Semasteint
2015254721SemasteGDBRemoteCommunicationClient::SetWorkingDir (char const *path)
2016254721Semaste{
2017254721Semaste    if (path && path[0])
2018254721Semaste    {
2019254721Semaste        StreamString packet;
2020254721Semaste        packet.PutCString("QSetWorkingDir:");
2021254721Semaste        packet.PutBytesAsRawHex8(path, strlen(path));
2022254721Semaste
2023254721Semaste        StringExtractorGDBRemote response;
2024269024Semaste        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
2025254721Semaste        {
2026254721Semaste            if (response.IsOKResponse())
2027254721Semaste                return 0;
2028254721Semaste            uint8_t error = response.GetError();
2029254721Semaste            if (error)
2030254721Semaste                return error;
2031254721Semaste        }
2032254721Semaste    }
2033254721Semaste    return -1;
2034254721Semaste}
2035254721Semaste
2036254721Semasteint
2037254721SemasteGDBRemoteCommunicationClient::SetDisableASLR (bool enable)
2038254721Semaste{
2039254721Semaste    char packet[32];
2040254721Semaste    const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
2041254721Semaste    assert (packet_len < (int)sizeof(packet));
2042254721Semaste    StringExtractorGDBRemote response;
2043269024Semaste    if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
2044254721Semaste    {
2045254721Semaste        if (response.IsOKResponse())
2046254721Semaste            return 0;
2047254721Semaste        uint8_t error = response.GetError();
2048254721Semaste        if (error)
2049254721Semaste            return error;
2050254721Semaste    }
2051254721Semaste    return -1;
2052254721Semaste}
2053254721Semaste
2054254721Semastebool
2055254721SemasteGDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
2056254721Semaste{
2057254721Semaste    if (response.IsNormalResponse())
2058254721Semaste    {
2059254721Semaste        std::string name;
2060254721Semaste        std::string value;
2061254721Semaste        StringExtractor extractor;
2062269024Semaste
2063269024Semaste        uint32_t cpu = LLDB_INVALID_CPUTYPE;
2064269024Semaste        uint32_t sub = 0;
2065269024Semaste        std::string vendor;
2066269024Semaste        std::string os_type;
2067254721Semaste
2068254721Semaste        while (response.GetNameColonValue(name, value))
2069254721Semaste        {
2070254721Semaste            if (name.compare("pid") == 0)
2071254721Semaste            {
2072254721Semaste                process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
2073254721Semaste            }
2074254721Semaste            else if (name.compare("ppid") == 0)
2075254721Semaste            {
2076254721Semaste                process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
2077254721Semaste            }
2078254721Semaste            else if (name.compare("uid") == 0)
2079254721Semaste            {
2080254721Semaste                process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
2081254721Semaste            }
2082254721Semaste            else if (name.compare("euid") == 0)
2083254721Semaste            {
2084254721Semaste                process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
2085254721Semaste            }
2086254721Semaste            else if (name.compare("gid") == 0)
2087254721Semaste            {
2088254721Semaste                process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
2089254721Semaste            }
2090254721Semaste            else if (name.compare("egid") == 0)
2091254721Semaste            {
2092254721Semaste                process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
2093254721Semaste            }
2094254721Semaste            else if (name.compare("triple") == 0)
2095254721Semaste            {
2096254721Semaste                // The triple comes as ASCII hex bytes since it contains '-' chars
2097254721Semaste                extractor.GetStringRef().swap(value);
2098254721Semaste                extractor.SetFilePos(0);
2099254721Semaste                extractor.GetHexByteString (value);
2100254721Semaste                process_info.GetArchitecture ().SetTriple (value.c_str());
2101254721Semaste            }
2102254721Semaste            else if (name.compare("name") == 0)
2103254721Semaste            {
2104254721Semaste                StringExtractor extractor;
2105254721Semaste                // The process name from ASCII hex bytes since we can't
2106254721Semaste                // control the characters in a process name
2107254721Semaste                extractor.GetStringRef().swap(value);
2108254721Semaste                extractor.SetFilePos(0);
2109254721Semaste                extractor.GetHexByteString (value);
2110254721Semaste                process_info.GetExecutableFile().SetFile (value.c_str(), false);
2111254721Semaste            }
2112269024Semaste            else if (name.compare("cputype") == 0)
2113269024Semaste            {
2114269024Semaste                cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
2115269024Semaste            }
2116269024Semaste            else if (name.compare("cpusubtype") == 0)
2117269024Semaste            {
2118269024Semaste                sub = Args::StringToUInt32 (value.c_str(), 0, 16);
2119269024Semaste            }
2120269024Semaste            else if (name.compare("vendor") == 0)
2121269024Semaste            {
2122269024Semaste                vendor = value;
2123269024Semaste            }
2124269024Semaste            else if (name.compare("ostype") == 0)
2125269024Semaste            {
2126269024Semaste                os_type = value;
2127269024Semaste            }
2128254721Semaste        }
2129269024Semaste
2130269024Semaste        if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty())
2131269024Semaste        {
2132269024Semaste            if (vendor == "apple")
2133269024Semaste            {
2134269024Semaste                process_info.GetArchitecture().SetArchitecture (eArchTypeMachO, cpu, sub);
2135269024Semaste                process_info.GetArchitecture().GetTriple().setVendorName (llvm::StringRef (vendor));
2136269024Semaste                process_info.GetArchitecture().GetTriple().setOSName (llvm::StringRef (os_type));
2137269024Semaste            }
2138269024Semaste        }
2139254721Semaste
2140254721Semaste        if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
2141254721Semaste            return true;
2142254721Semaste    }
2143254721Semaste    return false;
2144254721Semaste}
2145254721Semaste
2146254721Semastebool
2147254721SemasteGDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
2148254721Semaste{
2149254721Semaste    process_info.Clear();
2150254721Semaste
2151254721Semaste    if (m_supports_qProcessInfoPID)
2152254721Semaste    {
2153254721Semaste        char packet[32];
2154254721Semaste        const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
2155254721Semaste        assert (packet_len < (int)sizeof(packet));
2156254721Semaste        StringExtractorGDBRemote response;
2157269024Semaste        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
2158254721Semaste        {
2159254721Semaste            return DecodeProcessInfoResponse (response, process_info);
2160254721Semaste        }
2161254721Semaste        else
2162254721Semaste        {
2163254721Semaste            m_supports_qProcessInfoPID = false;
2164254721Semaste            return false;
2165254721Semaste        }
2166254721Semaste    }
2167254721Semaste    return false;
2168254721Semaste}
2169254721Semaste
2170254721Semastebool
2171254721SemasteGDBRemoteCommunicationClient::GetCurrentProcessInfo ()
2172254721Semaste{
2173254721Semaste    if (m_qProcessInfo_is_valid == eLazyBoolYes)
2174254721Semaste        return true;
2175254721Semaste    if (m_qProcessInfo_is_valid == eLazyBoolNo)
2176254721Semaste        return false;
2177254721Semaste
2178254721Semaste    GetHostInfo ();
2179254721Semaste
2180254721Semaste    StringExtractorGDBRemote response;
2181269024Semaste    if (SendPacketAndWaitForResponse ("qProcessInfo", response, false) == PacketResult::Success)
2182254721Semaste    {
2183254721Semaste        if (response.IsNormalResponse())
2184254721Semaste        {
2185254721Semaste            std::string name;
2186254721Semaste            std::string value;
2187254721Semaste            uint32_t cpu = LLDB_INVALID_CPUTYPE;
2188254721Semaste            uint32_t sub = 0;
2189254721Semaste            std::string arch_name;
2190254721Semaste            std::string os_name;
2191254721Semaste            std::string vendor_name;
2192254721Semaste            std::string triple;
2193254721Semaste            uint32_t pointer_byte_size = 0;
2194254721Semaste            StringExtractor extractor;
2195254721Semaste            ByteOrder byte_order = eByteOrderInvalid;
2196254721Semaste            uint32_t num_keys_decoded = 0;
2197254721Semaste            while (response.GetNameColonValue(name, value))
2198254721Semaste            {
2199254721Semaste                if (name.compare("cputype") == 0)
2200254721Semaste                {
2201254721Semaste                    cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
2202254721Semaste                    if (cpu != LLDB_INVALID_CPUTYPE)
2203254721Semaste                        ++num_keys_decoded;
2204254721Semaste                }
2205254721Semaste                else if (name.compare("cpusubtype") == 0)
2206254721Semaste                {
2207254721Semaste                    sub = Args::StringToUInt32 (value.c_str(), 0, 16);
2208254721Semaste                    if (sub != 0)
2209254721Semaste                        ++num_keys_decoded;
2210254721Semaste                }
2211254721Semaste                else if (name.compare("ostype") == 0)
2212254721Semaste                {
2213254721Semaste                    os_name.swap (value);
2214254721Semaste                    ++num_keys_decoded;
2215254721Semaste                }
2216254721Semaste                else if (name.compare("vendor") == 0)
2217254721Semaste                {
2218254721Semaste                    vendor_name.swap(value);
2219254721Semaste                    ++num_keys_decoded;
2220254721Semaste                }
2221254721Semaste                else if (name.compare("endian") == 0)
2222254721Semaste                {
2223254721Semaste                    ++num_keys_decoded;
2224254721Semaste                    if (value.compare("little") == 0)
2225254721Semaste                        byte_order = eByteOrderLittle;
2226254721Semaste                    else if (value.compare("big") == 0)
2227254721Semaste                        byte_order = eByteOrderBig;
2228254721Semaste                    else if (value.compare("pdp") == 0)
2229254721Semaste                        byte_order = eByteOrderPDP;
2230254721Semaste                    else
2231254721Semaste                        --num_keys_decoded;
2232254721Semaste                }
2233254721Semaste                else if (name.compare("ptrsize") == 0)
2234254721Semaste                {
2235254721Semaste                    pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 16);
2236254721Semaste                    if (pointer_byte_size != 0)
2237254721Semaste                        ++num_keys_decoded;
2238254721Semaste                }
2239254721Semaste            }
2240254721Semaste            if (num_keys_decoded > 0)
2241254721Semaste                m_qProcessInfo_is_valid = eLazyBoolYes;
2242254721Semaste            if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
2243254721Semaste            {
2244254721Semaste                m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
2245254721Semaste                if (pointer_byte_size)
2246254721Semaste                {
2247254721Semaste                    assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
2248254721Semaste                }
2249254721Semaste                m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
2250254721Semaste                m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
2251254721Semaste                return true;
2252254721Semaste            }
2253254721Semaste        }
2254254721Semaste    }
2255254721Semaste    else
2256254721Semaste    {
2257254721Semaste        m_qProcessInfo_is_valid = eLazyBoolNo;
2258254721Semaste    }
2259254721Semaste
2260254721Semaste    return false;
2261254721Semaste}
2262254721Semaste
2263254721Semaste
2264254721Semasteuint32_t
2265254721SemasteGDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
2266254721Semaste                                             ProcessInstanceInfoList &process_infos)
2267254721Semaste{
2268254721Semaste    process_infos.Clear();
2269254721Semaste
2270254721Semaste    if (m_supports_qfProcessInfo)
2271254721Semaste    {
2272254721Semaste        StreamString packet;
2273254721Semaste        packet.PutCString ("qfProcessInfo");
2274254721Semaste        if (!match_info.MatchAllProcesses())
2275254721Semaste        {
2276254721Semaste            packet.PutChar (':');
2277254721Semaste            const char *name = match_info.GetProcessInfo().GetName();
2278254721Semaste            bool has_name_match = false;
2279254721Semaste            if (name && name[0])
2280254721Semaste            {
2281254721Semaste                has_name_match = true;
2282254721Semaste                NameMatchType name_match_type = match_info.GetNameMatchType();
2283254721Semaste                switch (name_match_type)
2284254721Semaste                {
2285254721Semaste                case eNameMatchIgnore:
2286254721Semaste                    has_name_match = false;
2287254721Semaste                    break;
2288254721Semaste
2289254721Semaste                case eNameMatchEquals:
2290254721Semaste                    packet.PutCString ("name_match:equals;");
2291254721Semaste                    break;
2292254721Semaste
2293254721Semaste                case eNameMatchContains:
2294254721Semaste                    packet.PutCString ("name_match:contains;");
2295254721Semaste                    break;
2296254721Semaste
2297254721Semaste                case eNameMatchStartsWith:
2298254721Semaste                    packet.PutCString ("name_match:starts_with;");
2299254721Semaste                    break;
2300254721Semaste
2301254721Semaste                case eNameMatchEndsWith:
2302254721Semaste                    packet.PutCString ("name_match:ends_with;");
2303254721Semaste                    break;
2304254721Semaste
2305254721Semaste                case eNameMatchRegularExpression:
2306254721Semaste                    packet.PutCString ("name_match:regex;");
2307254721Semaste                    break;
2308254721Semaste                }
2309254721Semaste                if (has_name_match)
2310254721Semaste                {
2311254721Semaste                    packet.PutCString ("name:");
2312254721Semaste                    packet.PutBytesAsRawHex8(name, ::strlen(name));
2313254721Semaste                    packet.PutChar (';');
2314254721Semaste                }
2315254721Semaste            }
2316254721Semaste
2317254721Semaste            if (match_info.GetProcessInfo().ProcessIDIsValid())
2318254721Semaste                packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID());
2319254721Semaste            if (match_info.GetProcessInfo().ParentProcessIDIsValid())
2320254721Semaste                packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID());
2321254721Semaste            if (match_info.GetProcessInfo().UserIDIsValid())
2322254721Semaste                packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
2323254721Semaste            if (match_info.GetProcessInfo().GroupIDIsValid())
2324254721Semaste                packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID());
2325254721Semaste            if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
2326254721Semaste                packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
2327254721Semaste            if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2328254721Semaste                packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
2329254721Semaste            if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
2330254721Semaste                packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
2331254721Semaste            if (match_info.GetProcessInfo().GetArchitecture().IsValid())
2332254721Semaste            {
2333254721Semaste                const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
2334254721Semaste                const llvm::Triple &triple = match_arch.GetTriple();
2335254721Semaste                packet.PutCString("triple:");
2336254721Semaste                packet.PutCStringAsRawHex8(triple.getTriple().c_str());
2337254721Semaste                packet.PutChar (';');
2338254721Semaste            }
2339254721Semaste        }
2340254721Semaste        StringExtractorGDBRemote response;
2341269024Semaste        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
2342254721Semaste        {
2343254721Semaste            do
2344254721Semaste            {
2345254721Semaste                ProcessInstanceInfo process_info;
2346254721Semaste                if (!DecodeProcessInfoResponse (response, process_info))
2347254721Semaste                    break;
2348254721Semaste                process_infos.Append(process_info);
2349254721Semaste                response.GetStringRef().clear();
2350254721Semaste                response.SetFilePos(0);
2351269024Semaste            } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success);
2352254721Semaste        }
2353254721Semaste        else
2354254721Semaste        {
2355254721Semaste            m_supports_qfProcessInfo = false;
2356254721Semaste            return 0;
2357254721Semaste        }
2358254721Semaste    }
2359254721Semaste    return process_infos.GetSize();
2360254721Semaste
2361254721Semaste}
2362254721Semaste
2363254721Semastebool
2364254721SemasteGDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
2365254721Semaste{
2366254721Semaste    if (m_supports_qUserName)
2367254721Semaste    {
2368254721Semaste        char packet[32];
2369254721Semaste        const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
2370254721Semaste        assert (packet_len < (int)sizeof(packet));
2371254721Semaste        StringExtractorGDBRemote response;
2372269024Semaste        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
2373254721Semaste        {
2374254721Semaste            if (response.IsNormalResponse())
2375254721Semaste            {
2376254721Semaste                // Make sure we parsed the right number of characters. The response is
2377254721Semaste                // the hex encoded user name and should make up the entire packet.
2378254721Semaste                // If there are any non-hex ASCII bytes, the length won't match below..
2379254721Semaste                if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2380254721Semaste                    return true;
2381254721Semaste            }
2382254721Semaste        }
2383254721Semaste        else
2384254721Semaste        {
2385254721Semaste            m_supports_qUserName = false;
2386254721Semaste            return false;
2387254721Semaste        }
2388254721Semaste    }
2389254721Semaste    return false;
2390254721Semaste
2391254721Semaste}
2392254721Semaste
2393254721Semastebool
2394254721SemasteGDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
2395254721Semaste{
2396254721Semaste    if (m_supports_qGroupName)
2397254721Semaste    {
2398254721Semaste        char packet[32];
2399254721Semaste        const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
2400254721Semaste        assert (packet_len < (int)sizeof(packet));
2401254721Semaste        StringExtractorGDBRemote response;
2402269024Semaste        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
2403254721Semaste        {
2404254721Semaste            if (response.IsNormalResponse())
2405254721Semaste            {
2406254721Semaste                // Make sure we parsed the right number of characters. The response is
2407254721Semaste                // the hex encoded group name and should make up the entire packet.
2408254721Semaste                // If there are any non-hex ASCII bytes, the length won't match below..
2409254721Semaste                if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
2410254721Semaste                    return true;
2411254721Semaste            }
2412254721Semaste        }
2413254721Semaste        else
2414254721Semaste        {
2415254721Semaste            m_supports_qGroupName = false;
2416254721Semaste            return false;
2417254721Semaste        }
2418254721Semaste    }
2419254721Semaste    return false;
2420254721Semaste}
2421254721Semaste
2422254721Semastevoid
2423254721SemasteGDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
2424254721Semaste{
2425254721Semaste    uint32_t i;
2426254721Semaste    TimeValue start_time, end_time;
2427254721Semaste    uint64_t total_time_nsec;
2428254721Semaste    if (SendSpeedTestPacket (0, 0))
2429254721Semaste    {
2430269024Semaste        static uint32_t g_send_sizes[] = { 0, 64, 128, 512, 1024 };
2431269024Semaste        static uint32_t g_recv_sizes[] = { 0, 64, 128, 512, 1024 }; //, 4*1024, 8*1024, 16*1024, 32*1024, 48*1024, 64*1024, 96*1024, 128*1024 };
2432269024Semaste        const size_t k_num_send_sizes = sizeof(g_send_sizes)/sizeof(uint32_t);
2433269024Semaste        const size_t k_num_recv_sizes = sizeof(g_recv_sizes)/sizeof(uint32_t);
2434269024Semaste        const uint64_t k_recv_amount = 4*1024*1024; // Receive 4MB
2435269024Semaste        for (uint32_t send_idx = 0; send_idx < k_num_send_sizes; ++send_idx)
2436254721Semaste        {
2437269024Semaste            const uint32_t send_size = g_send_sizes[send_idx];
2438269024Semaste            for (uint32_t recv_idx = 0; recv_idx < k_num_recv_sizes; ++recv_idx)
2439254721Semaste            {
2440269024Semaste                const uint32_t recv_size = g_recv_sizes[recv_idx];
2441269024Semaste                StreamString packet;
2442269024Semaste                packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
2443269024Semaste                uint32_t bytes_left = send_size;
2444269024Semaste                while (bytes_left > 0)
2445269024Semaste                {
2446269024Semaste                    if (bytes_left >= 26)
2447269024Semaste                    {
2448269024Semaste                        packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2449269024Semaste                        bytes_left -= 26;
2450269024Semaste                    }
2451269024Semaste                    else
2452269024Semaste                    {
2453269024Semaste                        packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
2454269024Semaste                        bytes_left = 0;
2455269024Semaste                    }
2456269024Semaste                }
2457269024Semaste
2458254721Semaste                start_time = TimeValue::Now();
2459269024Semaste                if (recv_size == 0)
2460254721Semaste                {
2461269024Semaste                    for (i=0; i<num_packets; ++i)
2462269024Semaste                    {
2463269024Semaste                        StringExtractorGDBRemote response;
2464269024Semaste                        SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
2465269024Semaste                    }
2466254721Semaste                }
2467269024Semaste                else
2468269024Semaste                {
2469269024Semaste                    uint32_t bytes_read = 0;
2470269024Semaste                    while (bytes_read < k_recv_amount)
2471269024Semaste                    {
2472269024Semaste                        StringExtractorGDBRemote response;
2473269024Semaste                        SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
2474269024Semaste                        bytes_read += recv_size;
2475269024Semaste                    }
2476269024Semaste                }
2477254721Semaste                end_time = TimeValue::Now();
2478254721Semaste                total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
2479254721Semaste                if (recv_size == 0)
2480269024Semaste                {
2481269024Semaste                    float packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
2482269024Semaste                    printf ("%u qSpeedTest(send=%-7u, recv=%-7u) in %" PRIu64 ".%9.9" PRIu64 " sec for %f packets/sec.\n",
2483269024Semaste                            num_packets,
2484269024Semaste                            send_size,
2485269024Semaste                            recv_size,
2486269024Semaste                            total_time_nsec / TimeValue::NanoSecPerSec,
2487269024Semaste                            total_time_nsec % TimeValue::NanoSecPerSec,
2488269024Semaste                            packets_per_second);
2489269024Semaste                }
2490269024Semaste                else
2491269024Semaste                {
2492269024Semaste                    float mb_second = ((((float)k_recv_amount)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec) / (1024.0*1024.0);
2493269024Semaste                    printf ("%u qSpeedTest(send=%-7u, recv=%-7u) sent 4MB in %" PRIu64 ".%9.9" PRIu64 " sec for %f MB/sec.\n",
2494269024Semaste                            num_packets,
2495269024Semaste                            send_size,
2496269024Semaste                            recv_size,
2497269024Semaste                            total_time_nsec / TimeValue::NanoSecPerSec,
2498269024Semaste                            total_time_nsec % TimeValue::NanoSecPerSec,
2499269024Semaste                            mb_second);
2500269024Semaste                }
2501254721Semaste            }
2502254721Semaste        }
2503254721Semaste    }
2504254721Semaste}
2505254721Semaste
2506254721Semastebool
2507254721SemasteGDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size)
2508254721Semaste{
2509254721Semaste    StreamString packet;
2510254721Semaste    packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size);
2511254721Semaste    uint32_t bytes_left = send_size;
2512254721Semaste    while (bytes_left > 0)
2513254721Semaste    {
2514254721Semaste        if (bytes_left >= 26)
2515254721Semaste        {
2516254721Semaste            packet.PutCString("abcdefghijklmnopqrstuvwxyz");
2517254721Semaste            bytes_left -= 26;
2518254721Semaste        }
2519254721Semaste        else
2520254721Semaste        {
2521254721Semaste            packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz");
2522254721Semaste            bytes_left = 0;
2523254721Semaste        }
2524254721Semaste    }
2525254721Semaste
2526254721Semaste    StringExtractorGDBRemote response;
2527269024Semaste    return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)  == PacketResult::Success;
2528254721Semaste}
2529254721Semaste
2530254721Semasteuint16_t
2531269024SemasteGDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname)
2532254721Semaste{
2533263363Semaste    pid = LLDB_INVALID_PROCESS_ID;
2534254721Semaste    StringExtractorGDBRemote response;
2535263363Semaste    StreamString stream;
2536263367Semaste    stream.PutCString("qLaunchGDBServer;");
2537263363Semaste    std::string hostname;
2538269024Semaste    if (remote_accept_hostname  && remote_accept_hostname[0])
2539269024Semaste        hostname = remote_accept_hostname;
2540263363Semaste    else
2541263363Semaste    {
2542269024Semaste        if (Host::GetHostname (hostname))
2543269024Semaste        {
2544269024Semaste            // Make the GDB server we launch only accept connections from this host
2545269024Semaste            stream.Printf("host:%s;", hostname.c_str());
2546269024Semaste        }
2547269024Semaste        else
2548269024Semaste        {
2549269024Semaste            // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
2550269024Semaste            stream.Printf("host:*;");
2551269024Semaste        }
2552263363Semaste    }
2553263363Semaste    const char *packet = stream.GetData();
2554263363Semaste    int packet_len = stream.GetSize();
2555263363Semaste
2556269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2557263363Semaste    {
2558254721Semaste        std::string name;
2559254721Semaste        std::string value;
2560254721Semaste        uint16_t port = 0;
2561254721Semaste        while (response.GetNameColonValue(name, value))
2562254721Semaste        {
2563263363Semaste            if (name.compare("port") == 0)
2564254721Semaste                port = Args::StringToUInt32(value.c_str(), 0, 0);
2565263363Semaste            else if (name.compare("pid") == 0)
2566263363Semaste                pid = Args::StringToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
2567254721Semaste        }
2568254721Semaste        return port;
2569254721Semaste    }
2570254721Semaste    return 0;
2571254721Semaste}
2572254721Semaste
2573254721Semastebool
2574263363SemasteGDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
2575263363Semaste{
2576263363Semaste    StreamString stream;
2577263363Semaste    stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid);
2578263363Semaste    const char *packet = stream.GetData();
2579263363Semaste    int packet_len = stream.GetSize();
2580263363Semaste
2581263363Semaste    StringExtractorGDBRemote response;
2582269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2583263363Semaste    {
2584263363Semaste        if (response.IsOKResponse())
2585263363Semaste            return true;
2586263363Semaste    }
2587263363Semaste    return false;
2588263363Semaste}
2589263363Semaste
2590263363Semastebool
2591254721SemasteGDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
2592254721Semaste{
2593254721Semaste    if (m_curr_tid == tid)
2594254721Semaste        return true;
2595254721Semaste
2596254721Semaste    char packet[32];
2597254721Semaste    int packet_len;
2598254721Semaste    if (tid == UINT64_MAX)
2599254721Semaste        packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
2600254721Semaste    else
2601254721Semaste        packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
2602254721Semaste    assert (packet_len + 1 < (int)sizeof(packet));
2603254721Semaste    StringExtractorGDBRemote response;
2604269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2605254721Semaste    {
2606254721Semaste        if (response.IsOKResponse())
2607254721Semaste        {
2608254721Semaste            m_curr_tid = tid;
2609254721Semaste            return true;
2610254721Semaste        }
2611254721Semaste    }
2612254721Semaste    return false;
2613254721Semaste}
2614254721Semaste
2615254721Semastebool
2616254721SemasteGDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
2617254721Semaste{
2618254721Semaste    if (m_curr_tid_run == tid)
2619254721Semaste        return true;
2620254721Semaste
2621254721Semaste    char packet[32];
2622254721Semaste    int packet_len;
2623254721Semaste    if (tid == UINT64_MAX)
2624254721Semaste        packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
2625254721Semaste    else
2626254721Semaste        packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
2627254721Semaste
2628254721Semaste    assert (packet_len + 1 < (int)sizeof(packet));
2629254721Semaste    StringExtractorGDBRemote response;
2630269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2631254721Semaste    {
2632254721Semaste        if (response.IsOKResponse())
2633254721Semaste        {
2634254721Semaste            m_curr_tid_run = tid;
2635254721Semaste            return true;
2636254721Semaste        }
2637254721Semaste    }
2638254721Semaste    return false;
2639254721Semaste}
2640254721Semaste
2641254721Semastebool
2642254721SemasteGDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
2643254721Semaste{
2644269024Semaste    if (SendPacketAndWaitForResponse("?", 1, response, false) == PacketResult::Success)
2645254721Semaste        return response.IsNormalResponse();
2646254721Semaste    return false;
2647254721Semaste}
2648254721Semaste
2649254721Semastebool
2650254721SemasteGDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response)
2651254721Semaste{
2652254721Semaste    if (m_supports_qThreadStopInfo)
2653254721Semaste    {
2654254721Semaste        char packet[256];
2655254721Semaste        int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
2656254721Semaste        assert (packet_len < (int)sizeof(packet));
2657269024Semaste        if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2658254721Semaste        {
2659263363Semaste            if (response.IsUnsupportedResponse())
2660263363Semaste                m_supports_qThreadStopInfo = false;
2661263363Semaste            else if (response.IsNormalResponse())
2662254721Semaste                return true;
2663254721Semaste            else
2664254721Semaste                return false;
2665254721Semaste        }
2666254721Semaste        else
2667254721Semaste        {
2668254721Semaste            m_supports_qThreadStopInfo = false;
2669254721Semaste        }
2670254721Semaste    }
2671254721Semaste    return false;
2672254721Semaste}
2673254721Semaste
2674254721Semaste
2675254721Semasteuint8_t
2676254721SemasteGDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert,  addr_t addr, uint32_t length)
2677254721Semaste{
2678269024Semaste    // Check if the stub is known not to support this breakpoint type
2679269024Semaste    if (!SupportsGDBStoppointPacket(type))
2680269024Semaste        return UINT8_MAX;
2681269024Semaste    // Construct the breakpoint packet
2682254721Semaste    char packet[64];
2683254721Semaste    const int packet_len = ::snprintf (packet,
2684254721Semaste                                       sizeof(packet),
2685254721Semaste                                       "%c%i,%" PRIx64 ",%x",
2686254721Semaste                                       insert ? 'Z' : 'z',
2687254721Semaste                                       type,
2688254721Semaste                                       addr,
2689254721Semaste                                       length);
2690269024Semaste    // Check we havent overwritten the end of the packet buffer
2691254721Semaste    assert (packet_len + 1 < (int)sizeof(packet));
2692254721Semaste    StringExtractorGDBRemote response;
2693269024Semaste    // Try to send the breakpoint packet, and check that it was correctly sent
2694269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)
2695254721Semaste    {
2696269024Semaste        // Receive and OK packet when the breakpoint successfully placed
2697254721Semaste        if (response.IsOKResponse())
2698254721Semaste            return 0;
2699269024Semaste
2700269024Semaste        // Error while setting breakpoint, send back specific error
2701269024Semaste        if (response.IsErrorResponse())
2702254721Semaste            return response.GetError();
2703269024Semaste
2704269024Semaste        // Empty packet informs us that breakpoint is not supported
2705269024Semaste        if (response.IsUnsupportedResponse())
2706254721Semaste        {
2707269024Semaste            // Disable this breakpoint type since it is unsupported
2708269024Semaste            switch (type)
2709269024Semaste            {
2710254721Semaste            case eBreakpointSoftware:   m_supports_z0 = false; break;
2711254721Semaste            case eBreakpointHardware:   m_supports_z1 = false; break;
2712254721Semaste            case eWatchpointWrite:      m_supports_z2 = false; break;
2713254721Semaste            case eWatchpointRead:       m_supports_z3 = false; break;
2714254721Semaste            case eWatchpointReadWrite:  m_supports_z4 = false; break;
2715269024Semaste            }
2716254721Semaste        }
2717254721Semaste    }
2718269024Semaste    // Signal generic faliure
2719254721Semaste    return UINT8_MAX;
2720254721Semaste}
2721254721Semaste
2722254721Semastesize_t
2723254721SemasteGDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
2724254721Semaste                                                   bool &sequence_mutex_unavailable)
2725254721Semaste{
2726254721Semaste    Mutex::Locker locker;
2727254721Semaste    thread_ids.clear();
2728254721Semaste
2729254721Semaste    if (GetSequenceMutex (locker, "ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"))
2730254721Semaste    {
2731254721Semaste        sequence_mutex_unavailable = false;
2732254721Semaste        StringExtractorGDBRemote response;
2733254721Semaste
2734269024Semaste        PacketResult packet_result;
2735269024Semaste        for (packet_result = SendPacketAndWaitForResponseNoLock ("qfThreadInfo", strlen("qfThreadInfo"), response);
2736269024Semaste             packet_result == PacketResult::Success && response.IsNormalResponse();
2737269024Semaste             packet_result = SendPacketAndWaitForResponseNoLock ("qsThreadInfo", strlen("qsThreadInfo"), response))
2738254721Semaste        {
2739254721Semaste            char ch = response.GetChar();
2740254721Semaste            if (ch == 'l')
2741254721Semaste                break;
2742254721Semaste            if (ch == 'm')
2743254721Semaste            {
2744254721Semaste                do
2745254721Semaste                {
2746254721Semaste                    tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
2747254721Semaste
2748254721Semaste                    if (tid != LLDB_INVALID_THREAD_ID)
2749254721Semaste                    {
2750254721Semaste                        thread_ids.push_back (tid);
2751254721Semaste                    }
2752254721Semaste                    ch = response.GetChar();    // Skip the command separator
2753254721Semaste                } while (ch == ',');            // Make sure we got a comma separator
2754254721Semaste            }
2755254721Semaste        }
2756254721Semaste    }
2757254721Semaste    else
2758254721Semaste    {
2759254721Semaste#if defined (LLDB_CONFIGURATION_DEBUG)
2760254721Semaste        // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
2761254721Semaste#else
2762254721Semaste        Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
2763254721Semaste        if (log)
2764254721Semaste            log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
2765254721Semaste#endif
2766254721Semaste        sequence_mutex_unavailable = true;
2767254721Semaste    }
2768254721Semaste    return thread_ids.size();
2769254721Semaste}
2770254721Semaste
2771254721Semastelldb::addr_t
2772254721SemasteGDBRemoteCommunicationClient::GetShlibInfoAddr()
2773254721Semaste{
2774254721Semaste    if (!IsRunning())
2775254721Semaste    {
2776254721Semaste        StringExtractorGDBRemote response;
2777269024Semaste        if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false) == PacketResult::Success)
2778254721Semaste        {
2779254721Semaste            if (response.IsNormalResponse())
2780254721Semaste                return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2781254721Semaste        }
2782254721Semaste    }
2783254721Semaste    return LLDB_INVALID_ADDRESS;
2784254721Semaste}
2785254721Semaste
2786263363Semastelldb_private::Error
2787263363SemasteGDBRemoteCommunicationClient::RunShellCommand (const char *command,           // Shouldn't be NULL
2788263363Semaste                                               const char *working_dir,       // Pass NULL to use the current working directory
2789263363Semaste                                               int *status_ptr,               // Pass NULL if you don't want the process exit status
2790263363Semaste                                               int *signo_ptr,                // Pass NULL if you don't want the signal that caused the process to exit
2791263363Semaste                                               std::string *command_output,   // Pass NULL if you don't want the command output
2792263363Semaste                                               uint32_t timeout_sec)          // Timeout in seconds to wait for shell program to finish
2793263363Semaste{
2794263363Semaste    lldb_private::StreamString stream;
2795263367Semaste    stream.PutCString("qPlatform_shell:");
2796263363Semaste    stream.PutBytesAsRawHex8(command, strlen(command));
2797263363Semaste    stream.PutChar(',');
2798263363Semaste    stream.PutHex32(timeout_sec);
2799263363Semaste    if (working_dir && *working_dir)
2800263363Semaste    {
2801263363Semaste        stream.PutChar(',');
2802263363Semaste        stream.PutBytesAsRawHex8(working_dir, strlen(working_dir));
2803263363Semaste    }
2804263363Semaste    const char *packet = stream.GetData();
2805263363Semaste    int packet_len = stream.GetSize();
2806263363Semaste    StringExtractorGDBRemote response;
2807269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2808263363Semaste    {
2809263363Semaste        if (response.GetChar() != 'F')
2810263363Semaste            return Error("malformed reply");
2811263363Semaste        if (response.GetChar() != ',')
2812263363Semaste            return Error("malformed reply");
2813263363Semaste        uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
2814263363Semaste        if (exitcode == UINT32_MAX)
2815263363Semaste            return Error("unable to run remote process");
2816263363Semaste        else if (status_ptr)
2817263363Semaste            *status_ptr = exitcode;
2818263363Semaste        if (response.GetChar() != ',')
2819263363Semaste            return Error("malformed reply");
2820263363Semaste        uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
2821263363Semaste        if (signo_ptr)
2822263363Semaste            *signo_ptr = signo;
2823263363Semaste        if (response.GetChar() != ',')
2824263363Semaste            return Error("malformed reply");
2825263363Semaste        std::string output;
2826263363Semaste        response.GetEscapedBinaryData(output);
2827263363Semaste        if (command_output)
2828263363Semaste            command_output->assign(output);
2829263363Semaste        return Error();
2830263363Semaste    }
2831263363Semaste    return Error("unable to send packet");
2832263363Semaste}
2833263363Semaste
2834263367SemasteError
2835263367SemasteGDBRemoteCommunicationClient::MakeDirectory (const char *path,
2836263367Semaste                                             uint32_t file_permissions)
2837263363Semaste{
2838263363Semaste    lldb_private::StreamString stream;
2839263367Semaste    stream.PutCString("qPlatform_mkdir:");
2840263367Semaste    stream.PutHex32(file_permissions);
2841263363Semaste    stream.PutChar(',');
2842263367Semaste    stream.PutBytesAsRawHex8(path, strlen(path));
2843263363Semaste    const char *packet = stream.GetData();
2844263363Semaste    int packet_len = stream.GetSize();
2845263363Semaste    StringExtractorGDBRemote response;
2846269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2847263363Semaste    {
2848263367Semaste        return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
2849263363Semaste    }
2850263367Semaste    return Error();
2851263363Semaste
2852263363Semaste}
2853263363Semaste
2854263367SemasteError
2855263367SemasteGDBRemoteCommunicationClient::SetFilePermissions (const char *path,
2856263367Semaste                                                  uint32_t file_permissions)
2857263367Semaste{
2858263367Semaste    lldb_private::StreamString stream;
2859263367Semaste    stream.PutCString("qPlatform_chmod:");
2860263367Semaste    stream.PutHex32(file_permissions);
2861263367Semaste    stream.PutChar(',');
2862263367Semaste    stream.PutBytesAsRawHex8(path, strlen(path));
2863263367Semaste    const char *packet = stream.GetData();
2864263367Semaste    int packet_len = stream.GetSize();
2865263367Semaste    StringExtractorGDBRemote response;
2866269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2867263367Semaste    {
2868263367Semaste        return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
2869263367Semaste    }
2870263367Semaste    return Error();
2871263367Semaste
2872263367Semaste}
2873263367Semaste
2874263363Semastestatic uint64_t
2875263363SemasteParseHostIOPacketResponse (StringExtractorGDBRemote &response,
2876263363Semaste                           uint64_t fail_result,
2877263363Semaste                           Error &error)
2878263363Semaste{
2879263363Semaste    response.SetFilePos(0);
2880263363Semaste    if (response.GetChar() != 'F')
2881263363Semaste        return fail_result;
2882263363Semaste    int32_t result = response.GetS32 (-2);
2883263363Semaste    if (result == -2)
2884263363Semaste        return fail_result;
2885263363Semaste    if (response.GetChar() == ',')
2886263363Semaste    {
2887263363Semaste        int result_errno = response.GetS32 (-2);
2888263363Semaste        if (result_errno != -2)
2889263363Semaste            error.SetError(result_errno, eErrorTypePOSIX);
2890263363Semaste        else
2891263363Semaste            error.SetError(-1, eErrorTypeGeneric);
2892263363Semaste    }
2893263363Semaste    else
2894263363Semaste        error.Clear();
2895263363Semaste    return  result;
2896263363Semaste}
2897263363Semastelldb::user_id_t
2898263363SemasteGDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
2899263363Semaste                                        uint32_t flags,
2900263363Semaste                                        mode_t mode,
2901263363Semaste                                        Error &error)
2902263363Semaste{
2903263363Semaste    lldb_private::StreamString stream;
2904263363Semaste    stream.PutCString("vFile:open:");
2905263363Semaste    std::string path (file_spec.GetPath());
2906263363Semaste    if (path.empty())
2907263363Semaste        return UINT64_MAX;
2908263363Semaste    stream.PutCStringAsRawHex8(path.c_str());
2909263363Semaste    stream.PutChar(',');
2910263363Semaste    const uint32_t posix_open_flags = File::ConvertOpenOptionsForPOSIXOpen(flags);
2911263363Semaste    stream.PutHex32(posix_open_flags);
2912263363Semaste    stream.PutChar(',');
2913263363Semaste    stream.PutHex32(mode);
2914263363Semaste    const char* packet = stream.GetData();
2915263363Semaste    int packet_len = stream.GetSize();
2916263363Semaste    StringExtractorGDBRemote response;
2917269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2918263363Semaste    {
2919263363Semaste        return ParseHostIOPacketResponse (response, UINT64_MAX, error);
2920263363Semaste    }
2921263363Semaste    return UINT64_MAX;
2922263363Semaste}
2923263363Semaste
2924263363Semastebool
2925263363SemasteGDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
2926263363Semaste                                         Error &error)
2927263363Semaste{
2928263363Semaste    lldb_private::StreamString stream;
2929263363Semaste    stream.Printf("vFile:close:%i", (int)fd);
2930263363Semaste    const char* packet = stream.GetData();
2931263363Semaste    int packet_len = stream.GetSize();
2932263363Semaste    StringExtractorGDBRemote response;
2933269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2934263363Semaste    {
2935263363Semaste        return ParseHostIOPacketResponse (response, -1, error) == 0;
2936263363Semaste    }
2937263363Semaste    return false;
2938263363Semaste}
2939263363Semaste
2940263363Semaste// Extension of host I/O packets to get the file size.
2941263363Semastelldb::user_id_t
2942263363SemasteGDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
2943263363Semaste{
2944263363Semaste    lldb_private::StreamString stream;
2945263363Semaste    stream.PutCString("vFile:size:");
2946263363Semaste    std::string path (file_spec.GetPath());
2947263363Semaste    stream.PutCStringAsRawHex8(path.c_str());
2948263363Semaste    const char* packet = stream.GetData();
2949263363Semaste    int packet_len = stream.GetSize();
2950263363Semaste    StringExtractorGDBRemote response;
2951269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2952263363Semaste    {
2953263363Semaste        if (response.GetChar() != 'F')
2954263363Semaste            return UINT64_MAX;
2955263363Semaste        uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
2956263363Semaste        return retcode;
2957263363Semaste    }
2958263363Semaste    return UINT64_MAX;
2959263363Semaste}
2960263363Semaste
2961263367SemasteError
2962263367SemasteGDBRemoteCommunicationClient::GetFilePermissions(const char *path, uint32_t &file_permissions)
2963263363Semaste{
2964263367Semaste    Error error;
2965263363Semaste    lldb_private::StreamString stream;
2966263363Semaste    stream.PutCString("vFile:mode:");
2967263367Semaste    stream.PutCStringAsRawHex8(path);
2968263363Semaste    const char* packet = stream.GetData();
2969263363Semaste    int packet_len = stream.GetSize();
2970263363Semaste    StringExtractorGDBRemote response;
2971269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
2972263363Semaste    {
2973263363Semaste        if (response.GetChar() != 'F')
2974263363Semaste        {
2975263363Semaste            error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
2976263363Semaste        }
2977263367Semaste        else
2978263363Semaste        {
2979263367Semaste            const uint32_t mode = response.GetS32(-1);
2980263367Semaste            if (mode == -1)
2981263363Semaste            {
2982263367Semaste                if (response.GetChar() == ',')
2983263367Semaste                {
2984263367Semaste                    int response_errno = response.GetS32(-1);
2985263367Semaste                    if (response_errno > 0)
2986263367Semaste                        error.SetError(response_errno, lldb::eErrorTypePOSIX);
2987263367Semaste                    else
2988263367Semaste                        error.SetErrorToGenericError();
2989263367Semaste                }
2990263363Semaste                else
2991263363Semaste                    error.SetErrorToGenericError();
2992263363Semaste            }
2993263367Semaste            else
2994263367Semaste            {
2995263367Semaste                file_permissions = mode & (S_IRWXU|S_IRWXG|S_IRWXO);
2996263367Semaste            }
2997263363Semaste        }
2998263363Semaste    }
2999263363Semaste    else
3000263363Semaste    {
3001263363Semaste        error.SetErrorStringWithFormat ("failed to send '%s' packet", packet);
3002263363Semaste    }
3003263367Semaste    return error;
3004263363Semaste}
3005263363Semaste
3006263363Semasteuint64_t
3007263363SemasteGDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
3008263363Semaste                                        uint64_t offset,
3009263363Semaste                                        void *dst,
3010263363Semaste                                        uint64_t dst_len,
3011263363Semaste                                        Error &error)
3012263363Semaste{
3013263363Semaste    lldb_private::StreamString stream;
3014263363Semaste    stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset);
3015263363Semaste    const char* packet = stream.GetData();
3016263363Semaste    int packet_len = stream.GetSize();
3017263363Semaste    StringExtractorGDBRemote response;
3018269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
3019263363Semaste    {
3020263363Semaste        if (response.GetChar() != 'F')
3021263363Semaste            return 0;
3022263363Semaste        uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
3023263363Semaste        if (retcode == UINT32_MAX)
3024263363Semaste            return retcode;
3025263363Semaste        const char next = (response.Peek() ? *response.Peek() : 0);
3026263363Semaste        if (next == ',')
3027263363Semaste            return 0;
3028263363Semaste        if (next == ';')
3029263363Semaste        {
3030263363Semaste            response.GetChar(); // skip the semicolon
3031263363Semaste            std::string buffer;
3032263363Semaste            if (response.GetEscapedBinaryData(buffer))
3033263363Semaste            {
3034263363Semaste                const uint64_t data_to_write = std::min<uint64_t>(dst_len, buffer.size());
3035263363Semaste                if (data_to_write > 0)
3036263363Semaste                    memcpy(dst, &buffer[0], data_to_write);
3037263363Semaste                return data_to_write;
3038263363Semaste            }
3039263363Semaste        }
3040263363Semaste    }
3041263363Semaste    return 0;
3042263363Semaste}
3043263363Semaste
3044263363Semasteuint64_t
3045263363SemasteGDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
3046263363Semaste                                         uint64_t offset,
3047263363Semaste                                         const void* src,
3048263363Semaste                                         uint64_t src_len,
3049263363Semaste                                         Error &error)
3050263363Semaste{
3051263363Semaste    lldb_private::StreamGDBRemote stream;
3052263363Semaste    stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
3053263363Semaste    stream.PutEscapedBytes(src, src_len);
3054263363Semaste    const char* packet = stream.GetData();
3055263363Semaste    int packet_len = stream.GetSize();
3056263363Semaste    StringExtractorGDBRemote response;
3057269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
3058263363Semaste    {
3059263363Semaste        if (response.GetChar() != 'F')
3060263363Semaste        {
3061263363Semaste            error.SetErrorStringWithFormat("write file failed");
3062263363Semaste            return 0;
3063263363Semaste        }
3064263363Semaste        uint64_t bytes_written = response.GetU64(UINT64_MAX);
3065263363Semaste        if (bytes_written == UINT64_MAX)
3066263363Semaste        {
3067263363Semaste            error.SetErrorToGenericError();
3068263363Semaste            if (response.GetChar() == ',')
3069263363Semaste            {
3070263363Semaste                int response_errno = response.GetS32(-1);
3071263363Semaste                if (response_errno > 0)
3072263363Semaste                    error.SetError(response_errno, lldb::eErrorTypePOSIX);
3073263363Semaste            }
3074263363Semaste            return 0;
3075263363Semaste        }
3076263363Semaste        return bytes_written;
3077263363Semaste    }
3078263363Semaste    else
3079263363Semaste    {
3080263363Semaste        error.SetErrorString ("failed to send vFile:pwrite packet");
3081263363Semaste    }
3082263363Semaste    return 0;
3083263363Semaste}
3084263363Semaste
3085263367SemasteError
3086263367SemasteGDBRemoteCommunicationClient::CreateSymlink (const char *src, const char *dst)
3087263367Semaste{
3088263367Semaste    Error error;
3089263367Semaste    lldb_private::StreamGDBRemote stream;
3090263367Semaste    stream.PutCString("vFile:symlink:");
3091263367Semaste    // the unix symlink() command reverses its parameters where the dst if first,
3092263367Semaste    // so we follow suit here
3093263367Semaste    stream.PutCStringAsRawHex8(dst);
3094263367Semaste    stream.PutChar(',');
3095263367Semaste    stream.PutCStringAsRawHex8(src);
3096263367Semaste    const char* packet = stream.GetData();
3097263367Semaste    int packet_len = stream.GetSize();
3098263367Semaste    StringExtractorGDBRemote response;
3099269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
3100263367Semaste    {
3101263367Semaste        if (response.GetChar() == 'F')
3102263367Semaste        {
3103263367Semaste            uint32_t result = response.GetU32(UINT32_MAX);
3104263367Semaste            if (result != 0)
3105263367Semaste            {
3106263367Semaste                error.SetErrorToGenericError();
3107263367Semaste                if (response.GetChar() == ',')
3108263367Semaste                {
3109263367Semaste                    int response_errno = response.GetS32(-1);
3110263367Semaste                    if (response_errno > 0)
3111263367Semaste                        error.SetError(response_errno, lldb::eErrorTypePOSIX);
3112263367Semaste                }
3113263367Semaste            }
3114263367Semaste        }
3115263367Semaste        else
3116263367Semaste        {
3117263367Semaste            // Should have returned with 'F<result>[,<errno>]'
3118263367Semaste            error.SetErrorStringWithFormat("symlink failed");
3119263367Semaste        }
3120263367Semaste    }
3121263367Semaste    else
3122263367Semaste    {
3123263367Semaste        error.SetErrorString ("failed to send vFile:symlink packet");
3124263367Semaste    }
3125263367Semaste    return error;
3126263367Semaste}
3127263367Semaste
3128263367SemasteError
3129263367SemasteGDBRemoteCommunicationClient::Unlink (const char *path)
3130263367Semaste{
3131263367Semaste    Error error;
3132263367Semaste    lldb_private::StreamGDBRemote stream;
3133263367Semaste    stream.PutCString("vFile:unlink:");
3134263367Semaste    // the unix symlink() command reverses its parameters where the dst if first,
3135263367Semaste    // so we follow suit here
3136263367Semaste    stream.PutCStringAsRawHex8(path);
3137263367Semaste    const char* packet = stream.GetData();
3138263367Semaste    int packet_len = stream.GetSize();
3139263367Semaste    StringExtractorGDBRemote response;
3140269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
3141263367Semaste    {
3142263367Semaste        if (response.GetChar() == 'F')
3143263367Semaste        {
3144263367Semaste            uint32_t result = response.GetU32(UINT32_MAX);
3145263367Semaste            if (result != 0)
3146263367Semaste            {
3147263367Semaste                error.SetErrorToGenericError();
3148263367Semaste                if (response.GetChar() == ',')
3149263367Semaste                {
3150263367Semaste                    int response_errno = response.GetS32(-1);
3151263367Semaste                    if (response_errno > 0)
3152263367Semaste                        error.SetError(response_errno, lldb::eErrorTypePOSIX);
3153263367Semaste                }
3154263367Semaste            }
3155263367Semaste        }
3156263367Semaste        else
3157263367Semaste        {
3158263367Semaste            // Should have returned with 'F<result>[,<errno>]'
3159263367Semaste            error.SetErrorStringWithFormat("unlink failed");
3160263367Semaste        }
3161263367Semaste    }
3162263367Semaste    else
3163263367Semaste    {
3164263367Semaste        error.SetErrorString ("failed to send vFile:unlink packet");
3165263367Semaste    }
3166263367Semaste    return error;
3167263367Semaste}
3168263367Semaste
3169263363Semaste// Extension of host I/O packets to get whether a file exists.
3170263363Semastebool
3171263363SemasteGDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
3172263363Semaste{
3173263363Semaste    lldb_private::StreamString stream;
3174263363Semaste    stream.PutCString("vFile:exists:");
3175263363Semaste    std::string path (file_spec.GetPath());
3176263363Semaste    stream.PutCStringAsRawHex8(path.c_str());
3177263363Semaste    const char* packet = stream.GetData();
3178263363Semaste    int packet_len = stream.GetSize();
3179263363Semaste    StringExtractorGDBRemote response;
3180269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
3181263363Semaste    {
3182263363Semaste        if (response.GetChar() != 'F')
3183263363Semaste            return false;
3184263363Semaste        if (response.GetChar() != ',')
3185263363Semaste            return false;
3186263363Semaste        bool retcode = (response.GetChar() != '0');
3187263363Semaste        return retcode;
3188263363Semaste    }
3189263363Semaste    return false;
3190263363Semaste}
3191263363Semaste
3192263363Semastebool
3193263363SemasteGDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec,
3194263363Semaste                                            uint64_t &high,
3195263363Semaste                                            uint64_t &low)
3196263363Semaste{
3197263363Semaste    lldb_private::StreamString stream;
3198263363Semaste    stream.PutCString("vFile:MD5:");
3199263363Semaste    std::string path (file_spec.GetPath());
3200263363Semaste    stream.PutCStringAsRawHex8(path.c_str());
3201263363Semaste    const char* packet = stream.GetData();
3202263363Semaste    int packet_len = stream.GetSize();
3203263363Semaste    StringExtractorGDBRemote response;
3204269024Semaste    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
3205263363Semaste    {
3206263363Semaste        if (response.GetChar() != 'F')
3207263363Semaste            return false;
3208263363Semaste        if (response.GetChar() != ',')
3209263363Semaste            return false;
3210263363Semaste        if (response.Peek() && *response.Peek() == 'x')
3211263363Semaste            return false;
3212263363Semaste        low = response.GetHexMaxU64(false, UINT64_MAX);
3213263363Semaste        high = response.GetHexMaxU64(false, UINT64_MAX);
3214263363Semaste        return true;
3215263363Semaste    }
3216263363Semaste    return false;
3217263363Semaste}
3218263367Semaste
3219263367Semastebool
3220263367SemasteGDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response)
3221263367Semaste{
3222263367Semaste    Mutex::Locker locker;
3223263367Semaste    if (GetSequenceMutex (locker, "Didn't get sequence mutex for p packet."))
3224263367Semaste    {
3225263367Semaste        const bool thread_suffix_supported = GetThreadSuffixSupported();
3226263367Semaste
3227263367Semaste        if (thread_suffix_supported || SetCurrentThread(tid))
3228263367Semaste        {
3229263367Semaste            char packet[64];
3230263367Semaste            int packet_len = 0;
3231263367Semaste            if (thread_suffix_supported)
3232263367Semaste                packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, tid);
3233263367Semaste            else
3234263367Semaste                packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
3235263367Semaste            assert (packet_len < ((int)sizeof(packet) - 1));
3236269024Semaste            return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
3237263367Semaste        }
3238263367Semaste    }
3239263367Semaste    return false;
3240263367Semaste
3241263367Semaste}
3242263367Semaste
3243263367Semaste
3244263367Semastebool
3245263367SemasteGDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractorGDBRemote &response)
3246263367Semaste{
3247263367Semaste    Mutex::Locker locker;
3248263367Semaste    if (GetSequenceMutex (locker, "Didn't get sequence mutex for g packet."))
3249263367Semaste    {
3250263367Semaste        const bool thread_suffix_supported = GetThreadSuffixSupported();
3251263367Semaste
3252263367Semaste        if (thread_suffix_supported || SetCurrentThread(tid))
3253263367Semaste        {
3254263367Semaste            char packet[64];
3255263367Semaste            int packet_len = 0;
3256263367Semaste            // Get all registers in one packet
3257263367Semaste            if (thread_suffix_supported)
3258263367Semaste                packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", tid);
3259263367Semaste            else
3260263367Semaste                packet_len = ::snprintf (packet, sizeof(packet), "g");
3261263367Semaste            assert (packet_len < ((int)sizeof(packet) - 1));
3262269024Semaste            return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
3263263367Semaste        }
3264263367Semaste    }
3265263367Semaste    return false;
3266263367Semaste}
3267263367Semastebool
3268263367SemasteGDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save_id)
3269263367Semaste{
3270263367Semaste    save_id = 0; // Set to invalid save ID
3271263367Semaste    if (m_supports_QSaveRegisterState == eLazyBoolNo)
3272263367Semaste        return false;
3273263367Semaste
3274263367Semaste    m_supports_QSaveRegisterState = eLazyBoolYes;
3275263367Semaste    Mutex::Locker locker;
3276263367Semaste    if (GetSequenceMutex (locker, "Didn't get sequence mutex for QSaveRegisterState."))
3277263367Semaste    {
3278263367Semaste        const bool thread_suffix_supported = GetThreadSuffixSupported();
3279263367Semaste        if (thread_suffix_supported || SetCurrentThread(tid))
3280263367Semaste        {
3281263367Semaste            char packet[256];
3282263367Semaste            if (thread_suffix_supported)
3283263367Semaste                ::snprintf (packet, sizeof(packet), "QSaveRegisterState;thread:%4.4" PRIx64 ";", tid);
3284263367Semaste            else
3285263367Semaste                ::strncpy (packet, "QSaveRegisterState", sizeof(packet));
3286263367Semaste
3287263367Semaste            StringExtractorGDBRemote response;
3288263367Semaste
3289269024Semaste            if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
3290263367Semaste            {
3291263367Semaste                if (response.IsUnsupportedResponse())
3292263367Semaste                {
3293263367Semaste                    // This packet isn't supported, don't try calling it again
3294263367Semaste                    m_supports_QSaveRegisterState = eLazyBoolNo;
3295263367Semaste                }
3296263367Semaste
3297263367Semaste                const uint32_t response_save_id = response.GetU32(0);
3298263367Semaste                if (response_save_id != 0)
3299263367Semaste                {
3300263367Semaste                    save_id = response_save_id;
3301263367Semaste                    return true;
3302263367Semaste                }
3303263367Semaste            }
3304263367Semaste        }
3305263367Semaste    }
3306263367Semaste    return false;
3307263367Semaste}
3308263367Semaste
3309263367Semastebool
3310263367SemasteGDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t save_id)
3311263367Semaste{
3312263367Semaste    // We use the "m_supports_QSaveRegisterState" variable here becuase the
3313263367Semaste    // QSaveRegisterState and QRestoreRegisterState packets must both be supported in
3314263367Semaste    // order to be useful
3315263367Semaste    if (m_supports_QSaveRegisterState == eLazyBoolNo)
3316263367Semaste        return false;
3317263367Semaste
3318263367Semaste    Mutex::Locker locker;
3319263367Semaste    if (GetSequenceMutex (locker, "Didn't get sequence mutex for QRestoreRegisterState."))
3320263367Semaste    {
3321263367Semaste        const bool thread_suffix_supported = GetThreadSuffixSupported();
3322263367Semaste        if (thread_suffix_supported || SetCurrentThread(tid))
3323263367Semaste        {
3324263367Semaste            char packet[256];
3325263367Semaste            if (thread_suffix_supported)
3326263367Semaste                ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u;thread:%4.4" PRIx64 ";", save_id, tid);
3327263367Semaste            else
3328263367Semaste                ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u" PRIx64 ";", save_id);
3329263367Semaste
3330263367Semaste            StringExtractorGDBRemote response;
3331263367Semaste
3332269024Semaste            if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
3333263367Semaste            {
3334263367Semaste                if (response.IsOKResponse())
3335263367Semaste                {
3336263367Semaste                    return true;
3337263367Semaste                }
3338263367Semaste                else if (response.IsUnsupportedResponse())
3339263367Semaste                {
3340263367Semaste                    // This packet isn't supported, don't try calling this packet or
3341263367Semaste                    // QSaveRegisterState again...
3342263367Semaste                    m_supports_QSaveRegisterState = eLazyBoolNo;
3343263367Semaste                }
3344263367Semaste            }
3345263367Semaste        }
3346263367Semaste    }
3347263367Semaste    return false;
3348263367Semaste}
3349