[Lldb-commits] [lldb] r128070 - in /lldb/trunk: lldb.xcodeproj/ source/Plugins/Process/gdb-remote/ source/Utility/ tools/lldb-platform/

Greg Clayton gclayton at apple.com
Mon Mar 21 21:00:09 PDT 2011


Author: gclayton
Date: Mon Mar 21 23:00:09 2011
New Revision: 128070

URL: http://llvm.org/viewvc/llvm-project?rev=128070&view=rev
Log:
Split the GDBRemoteCommunication class into three classes:
GDBRemoteCommunication - The base GDB remote communication class
GDBRemoteCommunicationClient - designed to be used for clients the connect to
                               a remote GDB server
GDBRemoteCommunicationServer - designed to be used on the server side of a
                               GDB server implementation.




Added:
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
Modified:
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
    lldb/trunk/source/Utility/StringExtractorGDBRemote.h
    lldb/trunk/tools/lldb-platform/lldb-platform.cpp

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Mar 21 23:00:09 2011
@@ -56,6 +56,10 @@
 		26680336116005EF008E1FE4 /* SBBreakpointLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AF16CC7114086A1007A7B3F /* SBBreakpointLocation.cpp */; };
 		26680337116005F1008E1FE4 /* SBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AF16A9C11402D5B007A7B3F /* SBBreakpoint.cpp */; };
 		2668035C11601108008E1FE4 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26680207115FD0ED008E1FE4 /* LLDB.framework */; };
+		26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */; };
+		26744EF21338317700EF765A /* GDBRemoteCommunicationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 26744EEE1338317700EF765A /* GDBRemoteCommunicationClient.h */; };
+		26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */; };
+		26744EF41338317700EF765A /* GDBRemoteCommunicationServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 26744EF01338317700EF765A /* GDBRemoteCommunicationServer.h */; };
 		2689000013353DB600698AC0 /* BreakpointResolverAddress.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D0DD5010FE554D00271C65 /* BreakpointResolverAddress.h */; };
 		2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D0DD5310FE555900271C65 /* BreakpointResolverAddress.cpp */; };
 		2689000213353DB600698AC0 /* BreakpointResolverFileLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D0DD5110FE554D00271C65 /* BreakpointResolverFileLine.h */; };
@@ -635,6 +639,10 @@
 		266F5CBB12FC846200DFCE33 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Config.h; path = include/lldb/Host/Config.h; sourceTree = "<group>"; };
 		2672D8461189055500FF4019 /* CommandObjectFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectFrame.cpp; path = source/Commands/CommandObjectFrame.cpp; sourceTree = "<group>"; };
 		2672D8471189055500FF4019 /* CommandObjectFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectFrame.h; path = source/Commands/CommandObjectFrame.h; sourceTree = "<group>"; };
+		26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationClient.cpp; sourceTree = "<group>"; };
+		26744EEE1338317700EF765A /* GDBRemoteCommunicationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunicationClient.h; sourceTree = "<group>"; };
+		26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationServer.cpp; sourceTree = "<group>"; };
+		26744EF01338317700EF765A /* GDBRemoteCommunicationServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunicationServer.h; sourceTree = "<group>"; };
 		2675F6FE1332BE690067997B /* PlatformRemoteiOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformRemoteiOS.cpp; sourceTree = "<group>"; };
 		2675F6FF1332BE690067997B /* PlatformRemoteiOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRemoteiOS.h; sourceTree = "<group>"; };
 		2676A093119C93C8008A98EF /* StringExtractorGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractorGDBRemote.cpp; path = source/Utility/StringExtractorGDBRemote.cpp; sourceTree = "<group>"; };
@@ -2380,6 +2388,10 @@
 			children = (
 				2618EE5B1315B29C001D6D71 /* GDBRemoteCommunication.cpp */,
 				2618EE5C1315B29C001D6D71 /* GDBRemoteCommunication.h */,
+				26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */,
+				26744EEE1338317700EF765A /* GDBRemoteCommunicationClient.h */,
+				26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */,
+				26744EF01338317700EF765A /* GDBRemoteCommunicationServer.h */,
 				2618EE5D1315B29C001D6D71 /* GDBRemoteRegisterContext.cpp */,
 				2618EE5E1315B29C001D6D71 /* GDBRemoteRegisterContext.h */,
 				2618EE5F1315B29C001D6D71 /* ProcessGDBRemote.cpp */,
@@ -2483,6 +2495,8 @@
 				2689000C13353DB600698AC0 /* StoppointCallbackContext.h in Headers */,
 				2689000E13353DB600698AC0 /* StoppointLocation.h in Headers */,
 				2689001013353DB600698AC0 /* WatchpointLocation.h in Headers */,
+				26744EF21338317700EF765A /* GDBRemoteCommunicationClient.h in Headers */,
+				26744EF41338317700EF765A /* GDBRemoteCommunicationServer.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3038,6 +3052,8 @@
 				2689011213353E8200698AC0 /* StringExtractorGDBRemote.cpp in Sources */,
 				2689011313353E8200698AC0 /* PseudoTerminal.cpp in Sources */,
 				26B1FCC21338115F002886E2 /* Host.mm in Sources */,
+				26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */,
+				26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Mon Mar 21 23:00:09 2011
@@ -13,18 +13,11 @@
 // C Includes
 // C++ Includes
 // Other libraries and framework includes
-#include "llvm/ADT/Triple.h"
-#include "lldb/Interpreter/Args.h"
-#include "lldb/Core/ConnectionFileDescriptor.h"
 #include "lldb/Core/Log.h"
-#include "lldb/Core/State.h"
 #include "lldb/Core/StreamString.h"
-#include "lldb/Host/Host.h"
 #include "lldb/Host/TimeValue.h"
 
 // Project includes
-#include "Utility/StringExtractorGDBRemote.h"
-#include "ProcessGDBRemote.h"
 #include "ProcessGDBRemoteLog.h"
 
 using namespace lldb;
@@ -33,32 +26,13 @@
 //----------------------------------------------------------------------
 // GDBRemoteCommunication constructor
 //----------------------------------------------------------------------
-GDBRemoteCommunication::GDBRemoteCommunication() :
-    Communication("gdb-remote.packets"),
+GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char *listener_name) :
+    Communication(comm_name),
     m_packet_timeout (1),
-    m_supports_not_sending_acks (eLazyBoolCalculate),
-    m_supports_thread_suffix (eLazyBoolCalculate),
-    m_supports_qHostInfo (eLazyBoolCalculate),
-    m_supports_vCont_all (eLazyBoolCalculate),
-    m_supports_vCont_any (eLazyBoolCalculate),
-    m_supports_vCont_c (eLazyBoolCalculate),
-    m_supports_vCont_C (eLazyBoolCalculate),
-    m_supports_vCont_s (eLazyBoolCalculate),
-    m_supports_vCont_S (eLazyBoolCalculate),
-    m_rx_packet_listener ("gdbremote.rx_packet"),
+    m_rx_packet_listener (listener_name),
     m_sequence_mutex (Mutex::eMutexTypeRecursive),
     m_public_is_running (false),
-    m_private_is_running (false),
-    m_async_mutex (Mutex::eMutexTypeRecursive),
-    m_async_packet_predicate (false),
-    m_async_packet (),
-    m_async_response (),
-    m_async_signal (-1),
-    m_arch(),
-    m_os(),
-    m_vendor(),
-    m_byte_order(lldb::endian::InlHostByteOrder()),
-    m_pointer_byte_size(0)
+    m_private_is_running (false)
 {
     m_rx_packet_listener.StartListeningForEvents(this,
                                                  Communication::eBroadcastBitPacketAvailable  |
@@ -117,419 +91,6 @@
     return Write (&nack_char, 1, status, NULL) == 1;
 }
 
-bool
-GDBRemoteCommunication::GetSendAcks ()
-{
-    if (m_supports_not_sending_acks == eLazyBoolCalculate)
-    {
-        StringExtractorGDBRemote response;
-        m_supports_not_sending_acks = eLazyBoolNo;
-        if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
-        {
-            if (response.IsOKPacket())
-                m_supports_not_sending_acks = eLazyBoolYes;
-        }
-    }
-    return m_supports_not_sending_acks != eLazyBoolYes;
-}
-
-void
-GDBRemoteCommunication::ResetDiscoverableSettings()
-{
-    m_supports_not_sending_acks = eLazyBoolCalculate;
-    m_supports_thread_suffix = eLazyBoolCalculate;
-    m_supports_qHostInfo = eLazyBoolCalculate;
-    m_supports_vCont_c = eLazyBoolCalculate;
-    m_supports_vCont_C = eLazyBoolCalculate;
-    m_supports_vCont_s = eLazyBoolCalculate;
-    m_supports_vCont_S = eLazyBoolCalculate;
-    m_arch.Clear();
-    m_os.Clear();
-    m_vendor.Clear();
-    m_byte_order = lldb::endian::InlHostByteOrder();
-    m_pointer_byte_size = 0;
-}
-
-
-bool
-GDBRemoteCommunication::GetThreadSuffixSupported ()
-{
-    if (m_supports_thread_suffix == eLazyBoolCalculate)
-    {
-        StringExtractorGDBRemote response;
-        m_supports_thread_suffix = eLazyBoolNo;
-        if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
-        {
-            if (response.IsOKPacket())
-                m_supports_thread_suffix = eLazyBoolYes;
-        }
-    }
-    return m_supports_thread_suffix;
-}
-bool
-GDBRemoteCommunication::GetVContSupported (char flavor)
-{
-    if (m_supports_vCont_c == eLazyBoolCalculate)
-    {
-        StringExtractorGDBRemote response;
-        m_supports_vCont_any = eLazyBoolNo;
-        m_supports_vCont_all = eLazyBoolNo;
-        m_supports_vCont_c = eLazyBoolNo;
-        m_supports_vCont_C = eLazyBoolNo;
-        m_supports_vCont_s = eLazyBoolNo;
-        m_supports_vCont_S = eLazyBoolNo;
-        if (SendPacketAndWaitForResponse("vCont?", response, false))
-        {
-            const char *response_cstr = response.GetStringRef().c_str();
-            if (::strstr (response_cstr, ";c"))
-                m_supports_vCont_c = eLazyBoolYes;
-
-            if (::strstr (response_cstr, ";C"))
-                m_supports_vCont_C = eLazyBoolYes;
-
-            if (::strstr (response_cstr, ";s"))
-                m_supports_vCont_s = eLazyBoolYes;
-
-            if (::strstr (response_cstr, ";S"))
-                m_supports_vCont_S = eLazyBoolYes;
-
-            if (m_supports_vCont_c == eLazyBoolYes &&
-                m_supports_vCont_C == eLazyBoolYes &&
-                m_supports_vCont_s == eLazyBoolYes &&
-                m_supports_vCont_S == eLazyBoolYes)
-            {
-                m_supports_vCont_all = eLazyBoolYes;
-            }
-            
-            if (m_supports_vCont_c == eLazyBoolYes ||
-                m_supports_vCont_C == eLazyBoolYes ||
-                m_supports_vCont_s == eLazyBoolYes ||
-                m_supports_vCont_S == eLazyBoolYes)
-            {
-                m_supports_vCont_any = eLazyBoolYes;
-            }
-        }
-    }
-    
-    switch (flavor)
-    {
-    case 'a': return m_supports_vCont_any;
-    case 'A': return m_supports_vCont_all;
-    case 'c': return m_supports_vCont_c;
-    case 'C': return m_supports_vCont_C;
-    case 's': return m_supports_vCont_s;
-    case 'S': return m_supports_vCont_S;
-    default: break;
-    }
-    return false;
-}
-
-
-size_t
-GDBRemoteCommunication::SendPacketAndWaitForResponse
-(
-    const char *payload,
-    StringExtractorGDBRemote &response,
-    bool send_async
-)
-{
-    return SendPacketAndWaitForResponse (payload, 
-                                         ::strlen (payload),
-                                         response,
-                                         send_async);
-}
-
-size_t
-GDBRemoteCommunication::SendPacketAndWaitForResponse
-(
-    const char *payload,
-    size_t payload_length,
-    StringExtractorGDBRemote &response,
-    bool send_async
-)
-{
-    Mutex::Locker locker;
-    TimeValue timeout_time;
-    timeout_time = TimeValue::Now();
-    timeout_time.OffsetWithSeconds (m_packet_timeout);
-    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-
-    if (GetSequenceMutex (locker))
-    {
-        if (SendPacketNoLock (payload, strlen(payload)))
-            return WaitForPacketNoLock (response, &timeout_time);
-    }
-    else
-    {
-        if (send_async)
-        {
-            Mutex::Locker async_locker (m_async_mutex);
-            m_async_packet.assign(payload, payload_length);
-            m_async_packet_predicate.SetValue (true, eBroadcastNever);
-            
-            if (log) 
-                log->Printf ("async: async packet = %s", m_async_packet.c_str());
-
-            bool timed_out = false;
-            bool sent_interrupt = false;
-            if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
-            {
-                if (sent_interrupt)
-                {
-                    if (log) 
-                        log->Printf ("async: sent interrupt");
-                    if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
-                    {
-                        if (log) 
-                            log->Printf ("async: got response");
-                        response = m_async_response;
-                        return response.GetStringRef().size();
-                    }
-                    else
-                    {
-                        if (log) 
-                            log->Printf ("async: timed out waiting for response");
-                    }
-                    
-                    // Make sure we wait until the continue packet has been sent again...
-                    if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
-                    {
-                        if (log) 
-                            log->Printf ("async: timed out waiting for process to resume");
-                    }
-                }
-                else
-                {
-                    // We had a racy condition where we went to send the interrupt
-                    // yet we were able to get the loc
-                }
-            }
-            else
-            {
-                if (log) 
-                    log->Printf ("async: failed to interrupt");
-            }
-        }
-        else
-        {
-            if (log) 
-                log->Printf ("mutex taken and send_async == false, aborting packet");
-        }
-    }
-    return 0;
-}
-
-//template<typename _Tp>
-//class ScopedValueChanger
-//{
-//public:
-//    // Take a value reference and the value to assign it to when this class
-//    // instance goes out of scope.
-//    ScopedValueChanger (_Tp &value_ref, _Tp value) :
-//        m_value_ref (value_ref),
-//        m_value (value)
-//    {
-//    }
-//
-//    // This object is going out of scope, change the value pointed to by
-//    // m_value_ref to the value we got during construction which was stored in
-//    // m_value;
-//    ~ScopedValueChanger ()
-//    {
-//        m_value_ref = m_value;
-//    }
-//protected:
-//    _Tp &m_value_ref;   // A reference to the value we will change when this object destructs
-//    _Tp m_value;        // The value to assign to m_value_ref when this goes out of scope.
-//};
-
-StateType
-GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
-(
-    ProcessGDBRemote *process,
-    const char *payload,
-    size_t packet_length,
-    StringExtractorGDBRemote &response
-)
-{
-    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-    if (log)
-        log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
-
-    Mutex::Locker locker(m_sequence_mutex);
-    StateType state = eStateRunning;
-
-    BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
-    m_public_is_running.SetValue (true, eBroadcastNever);
-    // Set the starting continue packet into "continue_packet". This packet
-    // make change if we are interrupted and we continue after an async packet...
-    std::string continue_packet(payload, packet_length);
-    
-    while (state == eStateRunning)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
-        if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
-            state = eStateInvalid;
-        
-        m_private_is_running.SetValue (true, eBroadcastNever);
-
-        if (log)
-            log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
-
-        if (WaitForPacket (response, (TimeValue*)NULL))
-        {
-            if (response.Empty())
-                state = eStateInvalid;
-            else
-            {
-                const char stop_type = response.GetChar();
-                if (log)
-                    log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
-                switch (stop_type)
-                {
-                case 'T':
-                case 'S':
-                    if (process->GetStopID() == 0)
-                    {
-                        if (process->GetID() == LLDB_INVALID_PROCESS_ID)
-                        {
-                            lldb::pid_t pid = GetCurrentProcessID ();
-                            if (pid != LLDB_INVALID_PROCESS_ID)
-                                process->SetID (pid);
-                        }
-                        process->BuildDynamicRegisterInfo (true);
-                    }
-
-                    // Privately notify any internal threads that we have stopped
-                    // in case we wanted to interrupt our process, yet we might
-                    // send a packet and continue without returning control to the
-                    // user.
-                    m_private_is_running.SetValue (false, eBroadcastAlways);
-                    if (m_async_signal != -1)
-                    {
-                        if (log) 
-                            log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
-
-                        // Save off the async signal we are supposed to send
-                        const int async_signal = m_async_signal;
-                        // Clear the async signal member so we don't end up
-                        // sending the signal multiple times...
-                        m_async_signal = -1;
-                        // Check which signal we stopped with
-                        uint8_t signo = response.GetHexU8(255);
-                        if (signo == async_signal)
-                        {
-                            if (log) 
-                                log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
-
-                            // We already stopped with a signal that we wanted
-                            // to stop with, so we are done
-                            response.SetFilePos (0);
-                        }
-                        else
-                        {
-                            // We stopped with a different signal that the one
-                            // we wanted to stop with, so now we must resume
-                            // with the signal we want
-                            char signal_packet[32];
-                            int signal_packet_len = 0;
-                            signal_packet_len = ::snprintf (signal_packet,
-                                                            sizeof (signal_packet),
-                                                            "C%2.2x",
-                                                            async_signal);
-
-                            if (log) 
-                                log->Printf ("async: stopped with signal %s, resume with %s", 
-                                                   Host::GetSignalAsCString (signo),
-                                                   Host::GetSignalAsCString (async_signal));
-
-                            // Set the continue packet to resume...
-                            continue_packet.assign(signal_packet, signal_packet_len);
-                            continue;
-                        }
-                    }
-                    else if (m_async_packet_predicate.GetValue())
-                    {
-                        // We are supposed to send an asynchronous packet while
-                        // we are running. 
-                        m_async_response.Clear();
-                        if (m_async_packet.empty())
-                        {
-                            if (log) 
-                                log->Printf ("async: error: empty async packet");                            
-
-                        }
-                        else
-                        {
-                            if (log) 
-                                log->Printf ("async: sending packet: %s", 
-                                             m_async_packet.c_str());
-                            
-                            SendPacketAndWaitForResponse (&m_async_packet[0], 
-                                                          m_async_packet.size(),
-                                                          m_async_response,
-                                                          false);
-                        }
-                        // Let the other thread that was trying to send the async
-                        // packet know that the packet has been sent and response is
-                        // ready...
-                        m_async_packet_predicate.SetValue(false, eBroadcastAlways);
-
-                        // Set the continue packet to resume...
-                        continue_packet.assign (1, 'c');
-                        continue;
-                    }
-                    // Stop with signal and thread info
-                    state = eStateStopped;
-                    break;
-
-                case 'W':
-                case 'X':
-                    // process exited
-                    state = eStateExited;
-                    break;
-
-                case 'O':
-                    // STDOUT
-                    {
-                        std::string inferior_stdout;
-                        inferior_stdout.reserve(response.GetBytesLeft () / 2);
-                        char ch;
-                        while ((ch = response.GetHexU8()) != '\0')
-                            inferior_stdout.append(1, ch);
-                        process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
-                    }
-                    break;
-
-                case 'E':
-                    // ERROR
-                    state = eStateInvalid;
-                    break;
-
-                default:
-                    if (log)
-                        log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
-                    state = eStateInvalid;
-                    break;
-                }
-            }
-        }
-        else
-        {
-            if (log)
-                log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
-            state = eStateInvalid;
-        }
-    }
-    if (log)
-        log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
-    response.SetFilePos(0);
-    m_private_is_running.SetValue (false, eBroadcastAlways);
-    m_public_is_running.SetValue (false, eBroadcastAlways);
-    return state;
-}
-
 size_t
 GDBRemoteCommunication::SendPacket (const char *payload)
 {
@@ -583,9 +144,9 @@
 char
 GDBRemoteCommunication::GetAck ()
 {
-    StringExtractorGDBRemote response;
-    if (WaitForPacket (response, m_packet_timeout) == 1)
-        return response.GetChar();
+    StringExtractorGDBRemote packet;
+    if (WaitForPacket (packet, m_packet_timeout) == 1)
+        return packet.GetChar();
     return 0;
 }
 
@@ -595,98 +156,6 @@
     return locker.TryLock (m_sequence_mutex.GetMutex());
 }
 
-bool
-GDBRemoteCommunication::SendAsyncSignal (int signo)
-{
-    m_async_signal = signo;
-    bool timed_out = false;
-    bool sent_interrupt = false;
-    Mutex::Locker locker;
-    if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
-        return true;
-    m_async_signal = -1;
-    return false;
-}
-
-// This function takes a mutex locker as a parameter in case the GetSequenceMutex
-// actually succeeds. If it doesn't succeed in acquiring the sequence mutex 
-// (the expected result), then it will send the halt packet. If it does succeed
-// then the caller that requested the interrupt will want to keep the sequence
-// locked down so that no one else can send packets while the caller has control.
-// This function usually gets called when we are running and need to stop the 
-// target. It can also be used when we are running and and we need to do something
-// else (like read/write memory), so we need to interrupt the running process
-// (gdb remote protocol requires this), and do what we need to do, then resume.
-
-bool
-GDBRemoteCommunication::SendInterrupt 
-(
-    Mutex::Locker& locker, 
-    uint32_t seconds_to_wait_for_stop,             
-    bool &sent_interrupt,
-    bool &timed_out
-)
-{
-    sent_interrupt = false;
-    timed_out = false;
-    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-
-    if (IsRunning())
-    {
-        // Only send an interrupt if our debugserver is running...
-        if (GetSequenceMutex (locker) == false)
-        {
-            // Someone has the mutex locked waiting for a response or for the
-            // inferior to stop, so send the interrupt on the down low...
-            char ctrl_c = '\x03';
-            ConnectionStatus status = eConnectionStatusSuccess;
-            TimeValue timeout;
-            if (seconds_to_wait_for_stop)
-            {
-                timeout = TimeValue::Now();
-                timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
-            }
-            size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
-            ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
-            if (bytes_written > 0)
-            {
-                sent_interrupt = true;
-                if (seconds_to_wait_for_stop)
-                {
-                    if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
-                    {
-                        if (log)
-                            log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
-                        return true;
-                    }
-                    else
-                    {
-                        if (log)
-                            log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
-                    }
-                }
-                else
-                {
-                    if (log)
-                        log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);                    
-                    return true;
-                }
-            }
-            else
-            {
-                if (log)
-                    log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
-            }
-            return false;
-        }
-        else
-        {
-            if (log)
-                log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
-        }
-    }
-    return true;
-}
 
 bool
 GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
@@ -695,27 +164,27 @@
 }
 
 size_t
-GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
+GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &packet, uint32_t timeout_seconds)
 {
     Mutex::Locker locker(m_sequence_mutex);
     TimeValue timeout_time;
     timeout_time = TimeValue::Now();
     timeout_time.OffsetWithSeconds (timeout_seconds);
-    return WaitForPacketNoLock (response, &timeout_time);
+    return WaitForPacketNoLock (packet, &timeout_time);
 }
 
 size_t
-GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
+GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &packet, const TimeValue* timeout_time_ptr)
 {
     Mutex::Locker locker(m_sequence_mutex);
-    return WaitForPacketNoLock (response, timeout_time_ptr);
+    return WaitForPacketNoLock (packet, timeout_time_ptr);
 }
 
 size_t
-GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
+GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &packet, const TimeValue* timeout_time_ptr)
 {
     bool checksum_error = false;
-    response.Clear ();
+    packet.Clear ();
 
     EventSP event_sp;
 
@@ -734,7 +203,7 @@
                 const size_t packet_size =  event_bytes->GetByteSize();
                 if (packet_data && packet_size > 0)
                 {
-                    std::string &response_str = response.GetStringRef();
+                    std::string &packet_str = packet.GetStringRef();
                     if (packet_data[0] == '$')
                     {
                         bool success = false;
@@ -748,11 +217,11 @@
                             success = true;
                         
                         if (success)
-                            response_str.assign (packet_data + 1, packet_size - 4);
+                            packet_str.assign (packet_data + 1, packet_size - 4);
                         if (GetSendAcks ())
                         {
                             char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
-                            char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
+                            char actual_checksum = CalculcateChecksum (&packet_str[0], packet_str.size());
                             checksum_error = packet_checksum != actual_checksum;
                             // Send the ack or nack if needed
                             if (checksum_error || !success)
@@ -763,9 +232,9 @@
                     }
                     else
                     {
-                        response_str.assign (packet_data, packet_size);
+                        packet_str.assign (packet_data, packet_size);
                     }
-                    return response_str.size();
+                    return packet_str.size();
                 }
             }
         }
@@ -845,353 +314,3 @@
     }
 }
 
-lldb::pid_t
-GDBRemoteCommunication::GetCurrentProcessID ()
-{
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
-    {
-        if (response.GetChar() == 'Q')
-            if (response.GetChar() == 'C')
-                return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
-    }
-    return LLDB_INVALID_PROCESS_ID;
-}
-
-bool
-GDBRemoteCommunication::GetLaunchSuccess (std::string &error_str)
-{
-    error_str.clear();
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
-    {
-        if (response.IsOKPacket())
-            return true;
-        if (response.GetChar() == 'E')
-        {
-            // A string the describes what failed when launching...
-            error_str = response.GetStringRef().substr(1);
-        }
-        else
-        {
-            error_str.assign ("unknown error occurred launching process");
-        }
-    }
-    else
-    {
-        error_str.assign ("failed to send the qLaunchSuccess packet");
-    }
-    return false;
-}
-
-int
-GDBRemoteCommunication::SendArgumentsPacket (char const *argv[])
-{
-    if (argv && argv[0])
-    {
-        StreamString packet;
-        packet.PutChar('A');
-        const char *arg;
-        for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
-        {
-            const int arg_len = strlen(arg);
-            if (i > 0)
-                packet.PutChar(',');
-            packet.Printf("%i,%i,", arg_len * 2, i);
-            packet.PutBytesAsRawHex8 (arg, arg_len);
-        }
-
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
-        {
-            if (response.IsOKPacket())
-                return 0;
-            uint8_t error = response.GetError();
-            if (error)
-                return error;
-        }
-    }
-    return -1;
-}
-
-int
-GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value)
-{
-    if (name_equal_value && name_equal_value[0])
-    {
-        StreamString packet;
-        packet.Printf("QEnvironment:%s", name_equal_value);
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
-        {
-            if (response.IsOKPacket())
-                return 0;
-            uint8_t error = response.GetError();
-            if (error)
-                return error;
-        }
-    }
-    return -1;
-}
-
-bool
-GDBRemoteCommunication::GetHostInfo ()
-{
-    if (m_supports_qHostInfo == eLazyBoolCalculate)
-    {
-        m_supports_qHostInfo = eLazyBoolNo;
-
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
-        {
-            if (response.IsUnsupportedPacket())
-                return false;
-
-            m_supports_qHostInfo = eLazyBoolYes;
-
-            std::string name;
-            std::string value;
-            uint32_t cpu = LLDB_INVALID_CPUTYPE;
-            uint32_t sub = 0;
-        
-            while (response.GetNameColonValue(name, value))
-            {
-                if (name.compare("cputype") == 0)
-                {
-                    // exception type in big endian hex
-                    cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
-                }
-                else if (name.compare("cpusubtype") == 0)
-                {
-                    // exception count in big endian hex
-                    sub = Args::StringToUInt32 (value.c_str(), 0, 0);
-                }
-                else if (name.compare("ostype") == 0)
-                {
-                    // exception data in big endian hex
-                    m_os.SetCString(value.c_str());
-                }
-                else if (name.compare("vendor") == 0)
-                {
-                    m_vendor.SetCString(value.c_str());
-                }
-                else if (name.compare("endian") == 0)
-                {
-                    if (value.compare("little") == 0)
-                        m_byte_order = eByteOrderLittle;
-                    else if (value.compare("big") == 0)
-                        m_byte_order = eByteOrderBig;
-                    else if (value.compare("pdp") == 0)
-                        m_byte_order = eByteOrderPDP;
-                }
-                else if (name.compare("ptrsize") == 0)
-                {
-                    m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
-                }
-            }
-            
-            if (cpu != LLDB_INVALID_CPUTYPE)
-                m_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
-        }
-    }
-    return m_supports_qHostInfo == eLazyBoolYes;
-}
-
-int
-GDBRemoteCommunication::SendAttach 
-(
-    lldb::pid_t pid, 
-    StringExtractorGDBRemote& response
-)
-{
-    if (pid != LLDB_INVALID_PROCESS_ID)
-    {
-        StreamString packet;
-        packet.Printf("vAttach;%x", pid);
-        
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
-        {
-            if (response.IsErrorPacket())
-                return response.GetError();
-            return 0;
-        }
-    }
-    return -1;
-}
-
-const lldb_private::ArchSpec &
-GDBRemoteCommunication::GetHostArchitecture ()
-{
-    if (!HostInfoIsValid ())
-        GetHostInfo ();
-    return m_arch;
-}
-
-const lldb_private::ConstString &
-GDBRemoteCommunication::GetOSString ()
-{
-    if (!HostInfoIsValid ())
-        GetHostInfo ();
-    return m_os;
-}
-
-const lldb_private::ConstString &
-GDBRemoteCommunication::GetVendorString()
-{
-    if (!HostInfoIsValid ())
-        GetHostInfo ();
-    return m_vendor;
-}
-
-lldb::ByteOrder
-GDBRemoteCommunication::GetByteOrder ()
-{
-    if (!HostInfoIsValid ())
-        GetHostInfo ();
-    return m_byte_order;
-}
-
-uint32_t
-GDBRemoteCommunication::GetAddressByteSize ()
-{
-    if (!HostInfoIsValid ())
-        GetHostInfo ();
-    return m_pointer_byte_size;
-}
-
-addr_t
-GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions)
-{
-    char packet[64];
-    ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
-                permissions & lldb::ePermissionsReadable ? "r" : "",
-                permissions & lldb::ePermissionsWritable ? "w" : "",
-                permissions & lldb::ePermissionsExecutable ? "x" : "");
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse (packet, response, false))
-    {
-        if (!response.IsErrorPacket())
-            return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
-    }
-    return LLDB_INVALID_ADDRESS;
-}
-
-bool
-GDBRemoteCommunication::DeallocateMemory (addr_t addr)
-{
-    char packet[64];
-    snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse (packet, response, false))
-    {
-        if (response.IsOKPacket())
-            return true;
-    }
-    return false;
-}
-
-int
-GDBRemoteCommunication::SetSTDIN (char const *path)
-{
-    if (path && path[0])
-    {
-        StreamString packet;
-        packet.PutCString("QSetSTDIN:");
-        packet.PutBytesAsRawHex8(path, strlen(path));
-
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
-        {
-            if (response.IsOKPacket())
-                return 0;
-            uint8_t error = response.GetError();
-            if (error)
-                return error;
-        }
-    }
-    return -1;
-}
-
-int
-GDBRemoteCommunication::SetSTDOUT (char const *path)
-{
-    if (path && path[0])
-    {
-        StreamString packet;
-        packet.PutCString("QSetSTDOUT:");
-        packet.PutBytesAsRawHex8(path, strlen(path));
-        
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
-        {
-            if (response.IsOKPacket())
-                return 0;
-            uint8_t error = response.GetError();
-            if (error)
-                return error;
-        }
-    }
-    return -1;
-}
-
-int
-GDBRemoteCommunication::SetSTDERR (char const *path)
-{
-    if (path && path[0])
-    {
-        StreamString packet;
-        packet.PutCString("QSetSTDERR:");
-        packet.PutBytesAsRawHex8(path, strlen(path));
-        
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
-        {
-            if (response.IsOKPacket())
-                return 0;
-            uint8_t error = response.GetError();
-            if (error)
-                return error;
-        }
-    }
-    return -1;
-}
-
-int
-GDBRemoteCommunication::SetWorkingDir (char const *path)
-{
-    if (path && path[0])
-    {
-        StreamString packet;
-        packet.PutCString("QSetWorkingDir:");
-        packet.PutBytesAsRawHex8(path, strlen(path));
-        
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
-        {
-            if (response.IsOKPacket())
-                return 0;
-            uint8_t error = response.GetError();
-            if (error)
-                return error;
-        }
-    }
-    return -1;
-}
-
-int
-GDBRemoteCommunication::SetDisableASLR (bool enable)
-{
-    StreamString packet;
-    packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0);
-       
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
-    {
-        if (response.IsOKPacket())
-            return 0;
-        uint8_t error = response.GetError();
-        if (error)
-            return error;
-    }
-    return -1;
-}

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Mon Mar 21 23:00:09 2011
@@ -18,10 +18,7 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/lldb-private.h"
-#include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/Communication.h"
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Error.h"
 #include "lldb/Core/Listener.h"
 #include "lldb/Host/Mutex.h"
 #include "lldb/Host/Predicate.h"
@@ -30,8 +27,7 @@
 
 class ProcessGDBRemote;
 
-class GDBRemoteCommunication :
-    public lldb_private::Communication
+class GDBRemoteCommunication : public lldb_private::Communication
 {
 public:
     enum
@@ -41,7 +37,7 @@
     //------------------------------------------------------------------
     // Constructors and Destructors
     //------------------------------------------------------------------
-    GDBRemoteCommunication();
+    GDBRemoteCommunication(const char *comm_name, const char *listener_name);
 
     virtual
     ~GDBRemoteCommunication();
@@ -53,23 +49,6 @@
     SendPacket (const char *payload,
                 size_t payload_length);
 
-    size_t
-    SendPacketAndWaitForResponse (const char *send_payload,
-                                  StringExtractorGDBRemote &response,
-                                  bool send_async);
-
-    size_t
-    SendPacketAndWaitForResponse (const char *send_payload,
-                                  size_t send_length,
-                                  StringExtractorGDBRemote &response,
-                                  bool send_async);
-
-    lldb::StateType
-    SendContinuePacketAndWaitForResponse (ProcessGDBRemote *process,
-                                          const char *packet_payload,
-                                          size_t packet_length,
-                                          StringExtractorGDBRemote &response);
-
     // Wait for a packet within 'nsec' seconds
     size_t
     WaitForPacket (StringExtractorGDBRemote &response,
@@ -90,24 +69,11 @@
     size_t
     SendNack ();
 
-
     char
     CalculcateChecksum (const char *payload,
                         size_t payload_length);
 
     bool
-    GetThreadSuffixSupported ();
-
-    bool
-    SendAsyncSignal (int signo);
-
-    bool
-    SendInterrupt (lldb_private::Mutex::Locker &locker, 
-                   uint32_t seconds_to_wait_for_stop, 
-                   bool &sent_interrupt, 
-                   bool &timed_out);
-
-    bool
     GetSequenceMutex(lldb_private::Mutex::Locker& locker);
 
     //------------------------------------------------------------------
@@ -116,167 +82,29 @@
     virtual void
     AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status);
 
-
-    lldb::pid_t
-    GetCurrentProcessID ();
-
-    bool
-    GetLaunchSuccess (std::string &error_str);
-
-    //------------------------------------------------------------------
-    /// Sends a GDB remote protocol 'A' packet that delivers program
-    /// arguments to the remote server.
-    ///
-    /// @param[in] argv
-    ///     A NULL terminated array of const C strings to use as the
-    ///     arguments.
-    ///
-    /// @return
-    ///     Zero if the response was "OK", a positive value if the
-    ///     the response was "Exx" where xx are two hex digits, or
-    ///     -1 if the call is unsupported or any other unexpected
-    ///     response was received.
-    //------------------------------------------------------------------
-    int
-    SendArgumentsPacket (char const *argv[]);
-
-    //------------------------------------------------------------------
-    /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
-    /// environment that will get used when launching an application
-    /// in conjunction with the 'A' packet. This function can be called
-    /// multiple times in a row in order to pass on the desired
-    /// environment that the inferior should be launched with.
-    ///
-    /// @param[in] name_equal_value
-    ///     A NULL terminated C string that contains a single environment
-    ///     in the format "NAME=VALUE".
-    ///
-    /// @return
-    ///     Zero if the response was "OK", a positive value if the
-    ///     the response was "Exx" where xx are two hex digits, or
-    ///     -1 if the call is unsupported or any other unexpected
-    ///     response was received.
-    //------------------------------------------------------------------
-    int
-    SendEnvironmentPacket (char const *name_equal_value);
-
-    //------------------------------------------------------------------
-    /// Sends a "vAttach:PID" where PID is in hex. 
-    ///
-    /// @param[in] pid
-    ///     A process ID for the remote gdb server to attach to.
-    ///
-    /// @param[out] response
-    ///     The response received from the gdb server. If the return
-    ///     value is zero, \a response will contain a stop reply 
-    ///     packet.
-    ///
-    /// @return
-    ///     Zero if the attach was successful, or an error indicating
-    ///     an error code.
-    //------------------------------------------------------------------
-    int
-    SendAttach (lldb::pid_t pid, 
-                StringExtractorGDBRemote& response);
-
-
-    //------------------------------------------------------------------
-    /// Sets the path to use for stdin/out/err for a process
-    /// that will be launched with the 'A' packet.
-    ///
-    /// @param[in] path
-    ///     The path to use for stdin/out/err
-    ///
-    /// @return
-    ///     Zero if the for success, or an error code for failure.
-    //------------------------------------------------------------------
-    int
-    SetSTDIN (char const *path);
-    int
-    SetSTDOUT (char const *path);
-    int
-    SetSTDERR (char const *path);
-
-    //------------------------------------------------------------------
-    /// Sets the disable ASLR flag to \a enable for a process that will 
-    /// be launched with the 'A' packet.
-    ///
-    /// @param[in] enable
-    ///     A boolean value indicating wether to disable ASLR or not.
-    ///
-    /// @return
-    ///     Zero if the for success, or an error code for failure.
-    //------------------------------------------------------------------
-    int
-    SetDisableASLR (bool enable);
-
-    //------------------------------------------------------------------
-    /// Sets the working directory to \a path for a process that will 
-    /// be launched with the 'A' packet.
-    ///
-    /// @param[in] path
-    ///     The path to a directory to use when launching our processs
-    ///
-    /// @return
-    ///     Zero if the for success, or an error code for failure.
-    //------------------------------------------------------------------
-    int
-    SetWorkingDir (char const *path);
-
-    lldb::addr_t
-    AllocateMemory (size_t size, uint32_t permissions);
-
-    bool
-    DeallocateMemory (lldb::addr_t addr);
-
     bool
     IsRunning() const
     {
         return m_public_is_running.GetValue();
     }
 
-    const lldb_private::ArchSpec &
-    GetHostArchitecture ();
-    
-    const lldb_private::ConstString &
-    GetOSString ();
-    
-    const lldb_private::ConstString &
-    GetVendorString();
-    
-    lldb::ByteOrder
-    GetByteOrder ();
-
-    uint32_t
-    GetAddressByteSize ();
-
-    bool
-    GetVContSupported (char flavor);
-
-    void
-    ResetDiscoverableSettings();
-
-    bool
-    GetHostInfo ();
-    
-    bool
-    GetSendAcks ();
-    
-    bool
-    GetSupportsThreadSuffix ();
-
-    bool
-    HasFullVContSupport ()
-    {
-        return GetVContSupported ('A');
-    }
+    //------------------------------------------------------------------
+    // Client and server must implement these pure virtual functions
+    //------------------------------------------------------------------
+    virtual bool
+    GetThreadSuffixSupported () = 0;
 
-    bool
-    HasAnyVContSupport ()
-    {
-        return GetVContSupported ('a');
-    }
+    virtual bool
+    GetSendAcks () = 0;
     
+    //------------------------------------------------------------------
+    // Set the global packet timeout.
+    //
+    // For clients, this is the timeout that gets used when sending
+    // packets and waiting for responses. For servers, this might not
+    // get used, and if it doesn't this should be moved to the
+    // GDBRemoteCommunicationClient.
+    //------------------------------------------------------------------
     uint32_t 
     SetPacketTimeout (uint32_t packet_timeout)
     {
@@ -299,46 +127,15 @@
     bool
     WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
 
-    bool
-    HostInfoIsValid () const
-    {
-        return m_supports_qHostInfo != lldb::eLazyBoolCalculate;
-    }
-
     //------------------------------------------------------------------
     // Classes that inherit from GDBRemoteCommunication can see and modify these
     //------------------------------------------------------------------
     uint32_t m_packet_timeout;
-    lldb::LazyBool m_supports_not_sending_acks;
-    lldb::LazyBool m_supports_thread_suffix;
-    lldb::LazyBool m_supports_qHostInfo;
-    lldb::LazyBool m_supports_vCont_all;
-    lldb::LazyBool m_supports_vCont_any;
-    lldb::LazyBool m_supports_vCont_c;
-    lldb::LazyBool m_supports_vCont_C;
-    lldb::LazyBool m_supports_vCont_s;
-    lldb::LazyBool m_supports_vCont_S;
     lldb_private::Listener m_rx_packet_listener;
     lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
     lldb_private::Predicate<bool> m_public_is_running;
     lldb_private::Predicate<bool> m_private_is_running;
 
-    // If we need to send a packet while the target is running, the m_async_XXX
-    // member variables take care of making this happen.
-    lldb_private::Mutex m_async_mutex;
-    lldb_private::Predicate<bool> m_async_packet_predicate;
-    std::string m_async_packet;
-    StringExtractorGDBRemote m_async_response;
-    int m_async_signal; // We were asked to deliver a signal to the inferior process.
-    
-    lldb_private::ArchSpec m_arch;      // Results from the qHostInfo call
-    uint32_t m_cpusubtype;              // Results from the qHostInfo call
-    lldb_private::ConstString m_os;     // Results from the qHostInfo call
-    lldb_private::ConstString m_vendor; // Results from the qHostInfo call
-    lldb::ByteOrder m_byte_order;       // Results from the qHostInfo call
-    uint32_t m_pointer_byte_size;       // Results from the qHostInfo call
-    
-    
 private:
     //------------------------------------------------------------------
     // For GDBRemoteCommunication only

Added: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=128070&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (added)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Mon Mar 21 23:00:09 2011
@@ -0,0 +1,934 @@
+//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "GDBRemoteCommunicationClient.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/Triple.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/ConnectionFileDescriptor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/TimeValue.h"
+
+// Project includes
+#include "Utility/StringExtractorGDBRemote.h"
+#include "ProcessGDBRemote.h"
+#include "ProcessGDBRemoteLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// GDBRemoteCommunicationClient constructor
+//----------------------------------------------------------------------
+GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
+    GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
+    m_supports_not_sending_acks (eLazyBoolCalculate),
+    m_supports_thread_suffix (eLazyBoolCalculate),
+    m_supports_qHostInfo (eLazyBoolCalculate),
+    m_supports_vCont_all (eLazyBoolCalculate),
+    m_supports_vCont_any (eLazyBoolCalculate),
+    m_supports_vCont_c (eLazyBoolCalculate),
+    m_supports_vCont_C (eLazyBoolCalculate),
+    m_supports_vCont_s (eLazyBoolCalculate),
+    m_supports_vCont_S (eLazyBoolCalculate),
+    m_async_mutex (Mutex::eMutexTypeRecursive),
+    m_async_packet_predicate (false),
+    m_async_packet (),
+    m_async_response (),
+    m_async_signal (-1),
+    m_arch(),
+    m_os(),
+    m_vendor(),
+    m_byte_order(lldb::endian::InlHostByteOrder()),
+    m_pointer_byte_size(0)
+{
+    m_rx_packet_listener.StartListeningForEvents(this,
+                                                 Communication::eBroadcastBitPacketAvailable  |
+                                                 Communication::eBroadcastBitReadThreadDidExit);
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
+{
+    m_rx_packet_listener.StopListeningForEvents(this,
+                                                Communication::eBroadcastBitPacketAvailable  |
+                                                Communication::eBroadcastBitReadThreadDidExit);
+    if (IsConnected())
+    {
+        StopReadThread();
+        Disconnect();
+    }
+}
+
+bool
+GDBRemoteCommunicationClient::GetSendAcks ()
+{
+    if (m_supports_not_sending_acks == eLazyBoolCalculate)
+    {
+        StringExtractorGDBRemote response;
+        m_supports_not_sending_acks = eLazyBoolNo;
+        if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
+        {
+            if (response.IsOKResponse())
+                m_supports_not_sending_acks = eLazyBoolYes;
+        }
+    }
+    return m_supports_not_sending_acks != eLazyBoolYes;
+}
+
+void
+GDBRemoteCommunicationClient::ResetDiscoverableSettings()
+{
+    m_supports_not_sending_acks = eLazyBoolCalculate;
+    m_supports_thread_suffix = eLazyBoolCalculate;
+    m_supports_qHostInfo = eLazyBoolCalculate;
+    m_supports_vCont_c = eLazyBoolCalculate;
+    m_supports_vCont_C = eLazyBoolCalculate;
+    m_supports_vCont_s = eLazyBoolCalculate;
+    m_supports_vCont_S = eLazyBoolCalculate;
+    m_arch.Clear();
+    m_os.Clear();
+    m_vendor.Clear();
+    m_byte_order = lldb::endian::InlHostByteOrder();
+    m_pointer_byte_size = 0;
+}
+
+
+bool
+GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
+{
+    if (m_supports_thread_suffix == eLazyBoolCalculate)
+    {
+        StringExtractorGDBRemote response;
+        m_supports_thread_suffix = eLazyBoolNo;
+        if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
+        {
+            if (response.IsOKResponse())
+                m_supports_thread_suffix = eLazyBoolYes;
+        }
+    }
+    return m_supports_thread_suffix;
+}
+bool
+GDBRemoteCommunicationClient::GetVContSupported (char flavor)
+{
+    if (m_supports_vCont_c == eLazyBoolCalculate)
+    {
+        StringExtractorGDBRemote response;
+        m_supports_vCont_any = eLazyBoolNo;
+        m_supports_vCont_all = eLazyBoolNo;
+        m_supports_vCont_c = eLazyBoolNo;
+        m_supports_vCont_C = eLazyBoolNo;
+        m_supports_vCont_s = eLazyBoolNo;
+        m_supports_vCont_S = eLazyBoolNo;
+        if (SendPacketAndWaitForResponse("vCont?", response, false))
+        {
+            const char *response_cstr = response.GetStringRef().c_str();
+            if (::strstr (response_cstr, ";c"))
+                m_supports_vCont_c = eLazyBoolYes;
+
+            if (::strstr (response_cstr, ";C"))
+                m_supports_vCont_C = eLazyBoolYes;
+
+            if (::strstr (response_cstr, ";s"))
+                m_supports_vCont_s = eLazyBoolYes;
+
+            if (::strstr (response_cstr, ";S"))
+                m_supports_vCont_S = eLazyBoolYes;
+
+            if (m_supports_vCont_c == eLazyBoolYes &&
+                m_supports_vCont_C == eLazyBoolYes &&
+                m_supports_vCont_s == eLazyBoolYes &&
+                m_supports_vCont_S == eLazyBoolYes)
+            {
+                m_supports_vCont_all = eLazyBoolYes;
+            }
+            
+            if (m_supports_vCont_c == eLazyBoolYes ||
+                m_supports_vCont_C == eLazyBoolYes ||
+                m_supports_vCont_s == eLazyBoolYes ||
+                m_supports_vCont_S == eLazyBoolYes)
+            {
+                m_supports_vCont_any = eLazyBoolYes;
+            }
+        }
+    }
+    
+    switch (flavor)
+    {
+    case 'a': return m_supports_vCont_any;
+    case 'A': return m_supports_vCont_all;
+    case 'c': return m_supports_vCont_c;
+    case 'C': return m_supports_vCont_C;
+    case 's': return m_supports_vCont_s;
+    case 'S': return m_supports_vCont_S;
+    default: break;
+    }
+    return false;
+}
+
+
+size_t
+GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
+(
+    const char *payload,
+    StringExtractorGDBRemote &response,
+    bool send_async
+)
+{
+    return SendPacketAndWaitForResponse (payload, 
+                                         ::strlen (payload),
+                                         response,
+                                         send_async);
+}
+
+size_t
+GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
+(
+    const char *payload,
+    size_t payload_length,
+    StringExtractorGDBRemote &response,
+    bool send_async
+)
+{
+    Mutex::Locker locker;
+    TimeValue timeout_time;
+    timeout_time = TimeValue::Now();
+    timeout_time.OffsetWithSeconds (m_packet_timeout);
+    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+
+    if (GetSequenceMutex (locker))
+    {
+        if (SendPacketNoLock (payload, strlen(payload)))
+            return WaitForPacketNoLock (response, &timeout_time);
+    }
+    else
+    {
+        if (send_async)
+        {
+            Mutex::Locker async_locker (m_async_mutex);
+            m_async_packet.assign(payload, payload_length);
+            m_async_packet_predicate.SetValue (true, eBroadcastNever);
+            
+            if (log) 
+                log->Printf ("async: async packet = %s", m_async_packet.c_str());
+
+            bool timed_out = false;
+            bool sent_interrupt = false;
+            if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
+            {
+                if (sent_interrupt)
+                {
+                    if (log) 
+                        log->Printf ("async: sent interrupt");
+                    if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
+                    {
+                        if (log) 
+                            log->Printf ("async: got response");
+                        response = m_async_response;
+                        return response.GetStringRef().size();
+                    }
+                    else
+                    {
+                        if (log) 
+                            log->Printf ("async: timed out waiting for response");
+                    }
+                    
+                    // Make sure we wait until the continue packet has been sent again...
+                    if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
+                    {
+                        if (log) 
+                            log->Printf ("async: timed out waiting for process to resume");
+                    }
+                }
+                else
+                {
+                    // We had a racy condition where we went to send the interrupt
+                    // yet we were able to get the loc
+                }
+            }
+            else
+            {
+                if (log) 
+                    log->Printf ("async: failed to interrupt");
+            }
+        }
+        else
+        {
+            if (log) 
+                log->Printf ("mutex taken and send_async == false, aborting packet");
+        }
+    }
+    return 0;
+}
+
+//template<typename _Tp>
+//class ScopedValueChanger
+//{
+//public:
+//    // Take a value reference and the value to assign it to when this class
+//    // instance goes out of scope.
+//    ScopedValueChanger (_Tp &value_ref, _Tp value) :
+//        m_value_ref (value_ref),
+//        m_value (value)
+//    {
+//    }
+//
+//    // This object is going out of scope, change the value pointed to by
+//    // m_value_ref to the value we got during construction which was stored in
+//    // m_value;
+//    ~ScopedValueChanger ()
+//    {
+//        m_value_ref = m_value;
+//    }
+//protected:
+//    _Tp &m_value_ref;   // A reference to the value we will change when this object destructs
+//    _Tp m_value;        // The value to assign to m_value_ref when this goes out of scope.
+//};
+
+StateType
+GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
+(
+    ProcessGDBRemote *process,
+    const char *payload,
+    size_t packet_length,
+    StringExtractorGDBRemote &response
+)
+{
+    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+    if (log)
+        log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
+
+    Mutex::Locker locker(m_sequence_mutex);
+    StateType state = eStateRunning;
+
+    BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
+    m_public_is_running.SetValue (true, eBroadcastNever);
+    // Set the starting continue packet into "continue_packet". This packet
+    // make change if we are interrupted and we continue after an async packet...
+    std::string continue_packet(payload, packet_length);
+    
+    while (state == eStateRunning)
+    {
+        if (log)
+            log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
+        if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
+            state = eStateInvalid;
+        
+        m_private_is_running.SetValue (true, eBroadcastNever);
+
+        if (log)
+            log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%.*s)", __FUNCTION__);
+
+        if (WaitForPacket (response, (TimeValue*)NULL))
+        {
+            if (response.Empty())
+                state = eStateInvalid;
+            else
+            {
+                const char stop_type = response.GetChar();
+                if (log)
+                    log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
+                switch (stop_type)
+                {
+                case 'T':
+                case 'S':
+                    if (process->GetStopID() == 0)
+                    {
+                        if (process->GetID() == LLDB_INVALID_PROCESS_ID)
+                        {
+                            lldb::pid_t pid = GetCurrentProcessID ();
+                            if (pid != LLDB_INVALID_PROCESS_ID)
+                                process->SetID (pid);
+                        }
+                        process->BuildDynamicRegisterInfo (true);
+                    }
+
+                    // Privately notify any internal threads that we have stopped
+                    // in case we wanted to interrupt our process, yet we might
+                    // send a packet and continue without returning control to the
+                    // user.
+                    m_private_is_running.SetValue (false, eBroadcastAlways);
+                    if (m_async_signal != -1)
+                    {
+                        if (log) 
+                            log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
+
+                        // Save off the async signal we are supposed to send
+                        const int async_signal = m_async_signal;
+                        // Clear the async signal member so we don't end up
+                        // sending the signal multiple times...
+                        m_async_signal = -1;
+                        // Check which signal we stopped with
+                        uint8_t signo = response.GetHexU8(255);
+                        if (signo == async_signal)
+                        {
+                            if (log) 
+                                log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
+
+                            // We already stopped with a signal that we wanted
+                            // to stop with, so we are done
+                            response.SetFilePos (0);
+                        }
+                        else
+                        {
+                            // We stopped with a different signal that the one
+                            // we wanted to stop with, so now we must resume
+                            // with the signal we want
+                            char signal_packet[32];
+                            int signal_packet_len = 0;
+                            signal_packet_len = ::snprintf (signal_packet,
+                                                            sizeof (signal_packet),
+                                                            "C%2.2x",
+                                                            async_signal);
+
+                            if (log) 
+                                log->Printf ("async: stopped with signal %s, resume with %s", 
+                                                   Host::GetSignalAsCString (signo),
+                                                   Host::GetSignalAsCString (async_signal));
+
+                            // Set the continue packet to resume...
+                            continue_packet.assign(signal_packet, signal_packet_len);
+                            continue;
+                        }
+                    }
+                    else if (m_async_packet_predicate.GetValue())
+                    {
+                        // We are supposed to send an asynchronous packet while
+                        // we are running. 
+                        m_async_response.Clear();
+                        if (m_async_packet.empty())
+                        {
+                            if (log) 
+                                log->Printf ("async: error: empty async packet");                            
+
+                        }
+                        else
+                        {
+                            if (log) 
+                                log->Printf ("async: sending packet: %s", 
+                                             m_async_packet.c_str());
+                            
+                            SendPacketAndWaitForResponse (&m_async_packet[0], 
+                                                          m_async_packet.size(),
+                                                          m_async_response,
+                                                          false);
+                        }
+                        // Let the other thread that was trying to send the async
+                        // packet know that the packet has been sent and response is
+                        // ready...
+                        m_async_packet_predicate.SetValue(false, eBroadcastAlways);
+
+                        // Set the continue packet to resume...
+                        continue_packet.assign (1, 'c');
+                        continue;
+                    }
+                    // Stop with signal and thread info
+                    state = eStateStopped;
+                    break;
+
+                case 'W':
+                case 'X':
+                    // process exited
+                    state = eStateExited;
+                    break;
+
+                case 'O':
+                    // STDOUT
+                    {
+                        std::string inferior_stdout;
+                        inferior_stdout.reserve(response.GetBytesLeft () / 2);
+                        char ch;
+                        while ((ch = response.GetHexU8()) != '\0')
+                            inferior_stdout.append(1, ch);
+                        process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
+                    }
+                    break;
+
+                case 'E':
+                    // ERROR
+                    state = eStateInvalid;
+                    break;
+
+                default:
+                    if (log)
+                        log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
+                    state = eStateInvalid;
+                    break;
+                }
+            }
+        }
+        else
+        {
+            if (log)
+                log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
+            state = eStateInvalid;
+        }
+    }
+    if (log)
+        log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
+    response.SetFilePos(0);
+    m_private_is_running.SetValue (false, eBroadcastAlways);
+    m_public_is_running.SetValue (false, eBroadcastAlways);
+    return state;
+}
+
+bool
+GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
+{
+    m_async_signal = signo;
+    bool timed_out = false;
+    bool sent_interrupt = false;
+    Mutex::Locker locker;
+    if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
+        return true;
+    m_async_signal = -1;
+    return false;
+}
+
+// This function takes a mutex locker as a parameter in case the GetSequenceMutex
+// actually succeeds. If it doesn't succeed in acquiring the sequence mutex 
+// (the expected result), then it will send the halt packet. If it does succeed
+// then the caller that requested the interrupt will want to keep the sequence
+// locked down so that no one else can send packets while the caller has control.
+// This function usually gets called when we are running and need to stop the 
+// target. It can also be used when we are running and and we need to do something
+// else (like read/write memory), so we need to interrupt the running process
+// (gdb remote protocol requires this), and do what we need to do, then resume.
+
+bool
+GDBRemoteCommunicationClient::SendInterrupt 
+(
+    Mutex::Locker& locker, 
+    uint32_t seconds_to_wait_for_stop,             
+    bool &sent_interrupt,
+    bool &timed_out
+)
+{
+    sent_interrupt = false;
+    timed_out = false;
+    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+
+    if (IsRunning())
+    {
+        // Only send an interrupt if our debugserver is running...
+        if (GetSequenceMutex (locker) == false)
+        {
+            // Someone has the mutex locked waiting for a response or for the
+            // inferior to stop, so send the interrupt on the down low...
+            char ctrl_c = '\x03';
+            ConnectionStatus status = eConnectionStatusSuccess;
+            TimeValue timeout;
+            if (seconds_to_wait_for_stop)
+            {
+                timeout = TimeValue::Now();
+                timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
+            }
+            size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
+            ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
+            if (bytes_written > 0)
+            {
+                sent_interrupt = true;
+                if (seconds_to_wait_for_stop)
+                {
+                    if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
+                    {
+                        if (log)
+                            log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, private state stopped", __FUNCTION__);
+                        return true;
+                    }
+                    else
+                    {
+                        if (log)
+                            log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
+                    }
+                }
+                else
+                {
+                    if (log)
+                        log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);                    
+                    return true;
+                }
+            }
+            else
+            {
+                if (log)
+                    log->Printf ("GDBRemoteCommunicationClient::%s () - failed to write interrupt", __FUNCTION__);
+            }
+            return false;
+        }
+        else
+        {
+            if (log)
+                log->Printf ("GDBRemoteCommunicationClient::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
+        }
+    }
+    return true;
+}
+
+lldb::pid_t
+GDBRemoteCommunicationClient::GetCurrentProcessID ()
+{
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
+    {
+        if (response.GetChar() == 'Q')
+            if (response.GetChar() == 'C')
+                return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
+    }
+    return LLDB_INVALID_PROCESS_ID;
+}
+
+bool
+GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
+{
+    error_str.clear();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
+    {
+        if (response.IsOKResponse())
+            return true;
+        if (response.GetChar() == 'E')
+        {
+            // A string the describes what failed when launching...
+            error_str = response.GetStringRef().substr(1);
+        }
+        else
+        {
+            error_str.assign ("unknown error occurred launching process");
+        }
+    }
+    else
+    {
+        error_str.assign ("failed to send the qLaunchSuccess packet");
+    }
+    return false;
+}
+
+int
+GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
+{
+    if (argv && argv[0])
+    {
+        StreamString packet;
+        packet.PutChar('A');
+        const char *arg;
+        for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
+        {
+            const int arg_len = strlen(arg);
+            if (i > 0)
+                packet.PutChar(',');
+            packet.Printf("%i,%i,", arg_len * 2, i);
+            packet.PutBytesAsRawHex8 (arg, arg_len);
+        }
+
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+        {
+            if (response.IsOKResponse())
+                return 0;
+            uint8_t error = response.GetError();
+            if (error)
+                return error;
+        }
+    }
+    return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
+{
+    if (name_equal_value && name_equal_value[0])
+    {
+        StreamString packet;
+        packet.Printf("QEnvironment:%s", name_equal_value);
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+        {
+            if (response.IsOKResponse())
+                return 0;
+            uint8_t error = response.GetError();
+            if (error)
+                return error;
+        }
+    }
+    return -1;
+}
+
+bool
+GDBRemoteCommunicationClient::GetHostInfo ()
+{
+    if (m_supports_qHostInfo == eLazyBoolCalculate)
+    {
+        m_supports_qHostInfo = eLazyBoolNo;
+
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
+        {
+            if (response.IsUnsupportedResponse())
+                return false;
+
+            m_supports_qHostInfo = eLazyBoolYes;
+
+            std::string name;
+            std::string value;
+            uint32_t cpu = LLDB_INVALID_CPUTYPE;
+            uint32_t sub = 0;
+        
+            while (response.GetNameColonValue(name, value))
+            {
+                if (name.compare("cputype") == 0)
+                {
+                    // exception type in big endian hex
+                    cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
+                }
+                else if (name.compare("cpusubtype") == 0)
+                {
+                    // exception count in big endian hex
+                    sub = Args::StringToUInt32 (value.c_str(), 0, 0);
+                }
+                else if (name.compare("ostype") == 0)
+                {
+                    // exception data in big endian hex
+                    m_os.SetCString(value.c_str());
+                }
+                else if (name.compare("vendor") == 0)
+                {
+                    m_vendor.SetCString(value.c_str());
+                }
+                else if (name.compare("endian") == 0)
+                {
+                    if (value.compare("little") == 0)
+                        m_byte_order = eByteOrderLittle;
+                    else if (value.compare("big") == 0)
+                        m_byte_order = eByteOrderBig;
+                    else if (value.compare("pdp") == 0)
+                        m_byte_order = eByteOrderPDP;
+                }
+                else if (name.compare("ptrsize") == 0)
+                {
+                    m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+                }
+            }
+            
+            if (cpu != LLDB_INVALID_CPUTYPE)
+                m_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
+        }
+    }
+    return m_supports_qHostInfo == eLazyBoolYes;
+}
+
+int
+GDBRemoteCommunicationClient::SendAttach 
+(
+    lldb::pid_t pid, 
+    StringExtractorGDBRemote& response
+)
+{
+    if (pid != LLDB_INVALID_PROCESS_ID)
+    {
+        StreamString packet;
+        packet.Printf("vAttach;%x", pid);
+        
+        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+        {
+            if (response.IsErrorResponse())
+                return response.GetError();
+            return 0;
+        }
+    }
+    return -1;
+}
+
+const lldb_private::ArchSpec &
+GDBRemoteCommunicationClient::GetHostArchitecture ()
+{
+    if (!HostInfoIsValid ())
+        GetHostInfo ();
+    return m_arch;
+}
+
+const lldb_private::ConstString &
+GDBRemoteCommunicationClient::GetOSString ()
+{
+    if (!HostInfoIsValid ())
+        GetHostInfo ();
+    return m_os;
+}
+
+const lldb_private::ConstString &
+GDBRemoteCommunicationClient::GetVendorString()
+{
+    if (!HostInfoIsValid ())
+        GetHostInfo ();
+    return m_vendor;
+}
+
+lldb::ByteOrder
+GDBRemoteCommunicationClient::GetByteOrder ()
+{
+    if (!HostInfoIsValid ())
+        GetHostInfo ();
+    return m_byte_order;
+}
+
+uint32_t
+GDBRemoteCommunicationClient::GetAddressByteSize ()
+{
+    if (!HostInfoIsValid ())
+        GetHostInfo ();
+    return m_pointer_byte_size;
+}
+
+addr_t
+GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
+{
+    char packet[64];
+    ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
+                permissions & lldb::ePermissionsReadable ? "r" : "",
+                permissions & lldb::ePermissionsWritable ? "w" : "",
+                permissions & lldb::ePermissionsExecutable ? "x" : "");
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse (packet, response, false))
+    {
+        if (!response.IsErrorResponse())
+            return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+    }
+    return LLDB_INVALID_ADDRESS;
+}
+
+bool
+GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
+{
+    char packet[64];
+    snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse (packet, response, false))
+    {
+        if (response.IsOKResponse())
+            return true;
+    }
+    return false;
+}
+
+int
+GDBRemoteCommunicationClient::SetSTDIN (char const *path)
+{
+    if (path && path[0])
+    {
+        StreamString packet;
+        packet.PutCString("QSetSTDIN:");
+        packet.PutBytesAsRawHex8(path, strlen(path));
+
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+        {
+            if (response.IsOKResponse())
+                return 0;
+            uint8_t error = response.GetError();
+            if (error)
+                return error;
+        }
+    }
+    return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
+{
+    if (path && path[0])
+    {
+        StreamString packet;
+        packet.PutCString("QSetSTDOUT:");
+        packet.PutBytesAsRawHex8(path, strlen(path));
+        
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+        {
+            if (response.IsOKResponse())
+                return 0;
+            uint8_t error = response.GetError();
+            if (error)
+                return error;
+        }
+    }
+    return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SetSTDERR (char const *path)
+{
+    if (path && path[0])
+    {
+        StreamString packet;
+        packet.PutCString("QSetSTDERR:");
+        packet.PutBytesAsRawHex8(path, strlen(path));
+        
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+        {
+            if (response.IsOKResponse())
+                return 0;
+            uint8_t error = response.GetError();
+            if (error)
+                return error;
+        }
+    }
+    return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
+{
+    if (path && path[0])
+    {
+        StreamString packet;
+        packet.PutCString("QSetWorkingDir:");
+        packet.PutBytesAsRawHex8(path, strlen(path));
+        
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+        {
+            if (response.IsOKResponse())
+                return 0;
+            uint8_t error = response.GetError();
+            if (error)
+                return error;
+        }
+    }
+    return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
+{
+    StreamString packet;
+    packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0);
+       
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+    {
+        if (response.IsOKResponse())
+            return 0;
+        uint8_t error = response.GetError();
+        if (error)
+            return error;
+    }
+    return -1;
+}

Added: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=128070&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (added)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Mon Mar 21 23:00:09 2011
@@ -0,0 +1,268 @@
+//===-- GDBRemoteCommunicationClient.h --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_GDBRemoteCommunicationClient_h_
+#define liblldb_GDBRemoteCommunicationClient_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ArchSpec.h"
+
+#include "GDBRemoteCommunication.h"
+
+class GDBRemoteCommunicationClient : public GDBRemoteCommunication
+{
+public:
+    //------------------------------------------------------------------
+    // Constructors and Destructors
+    //------------------------------------------------------------------
+    GDBRemoteCommunicationClient();
+
+    virtual
+    ~GDBRemoteCommunicationClient();
+
+    size_t
+    SendPacketAndWaitForResponse (const char *send_payload,
+                                  StringExtractorGDBRemote &response,
+                                  bool send_async);
+
+    size_t
+    SendPacketAndWaitForResponse (const char *send_payload,
+                                  size_t send_length,
+                                  StringExtractorGDBRemote &response,
+                                  bool send_async);
+
+    lldb::StateType
+    SendContinuePacketAndWaitForResponse (ProcessGDBRemote *process,
+                                          const char *packet_payload,
+                                          size_t packet_length,
+                                          StringExtractorGDBRemote &response);
+
+    virtual bool
+    GetThreadSuffixSupported ();
+
+    virtual bool
+    GetSendAcks ();
+
+    bool
+    SendAsyncSignal (int signo);
+
+    bool
+    SendInterrupt (lldb_private::Mutex::Locker &locker, 
+                   uint32_t seconds_to_wait_for_stop, 
+                   bool &sent_interrupt, 
+                   bool &timed_out);
+
+    lldb::pid_t
+    GetCurrentProcessID ();
+
+    bool
+    GetLaunchSuccess (std::string &error_str);
+
+    //------------------------------------------------------------------
+    /// Sends a GDB remote protocol 'A' packet that delivers program
+    /// arguments to the remote server.
+    ///
+    /// @param[in] argv
+    ///     A NULL terminated array of const C strings to use as the
+    ///     arguments.
+    ///
+    /// @return
+    ///     Zero if the response was "OK", a positive value if the
+    ///     the response was "Exx" where xx are two hex digits, or
+    ///     -1 if the call is unsupported or any other unexpected
+    ///     response was received.
+    //------------------------------------------------------------------
+    int
+    SendArgumentsPacket (char const *argv[]);
+
+    //------------------------------------------------------------------
+    /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
+    /// environment that will get used when launching an application
+    /// in conjunction with the 'A' packet. This function can be called
+    /// multiple times in a row in order to pass on the desired
+    /// environment that the inferior should be launched with.
+    ///
+    /// @param[in] name_equal_value
+    ///     A NULL terminated C string that contains a single environment
+    ///     in the format "NAME=VALUE".
+    ///
+    /// @return
+    ///     Zero if the response was "OK", a positive value if the
+    ///     the response was "Exx" where xx are two hex digits, or
+    ///     -1 if the call is unsupported or any other unexpected
+    ///     response was received.
+    //------------------------------------------------------------------
+    int
+    SendEnvironmentPacket (char const *name_equal_value);
+
+    //------------------------------------------------------------------
+    /// Sends a "vAttach:PID" where PID is in hex. 
+    ///
+    /// @param[in] pid
+    ///     A process ID for the remote gdb server to attach to.
+    ///
+    /// @param[out] response
+    ///     The response received from the gdb server. If the return
+    ///     value is zero, \a response will contain a stop reply 
+    ///     packet.
+    ///
+    /// @return
+    ///     Zero if the attach was successful, or an error indicating
+    ///     an error code.
+    //------------------------------------------------------------------
+    int
+    SendAttach (lldb::pid_t pid, 
+                StringExtractorGDBRemote& response);
+
+
+    //------------------------------------------------------------------
+    /// Sets the path to use for stdin/out/err for a process
+    /// that will be launched with the 'A' packet.
+    ///
+    /// @param[in] path
+    ///     The path to use for stdin/out/err
+    ///
+    /// @return
+    ///     Zero if the for success, or an error code for failure.
+    //------------------------------------------------------------------
+    int
+    SetSTDIN (char const *path);
+    int
+    SetSTDOUT (char const *path);
+    int
+    SetSTDERR (char const *path);
+
+    //------------------------------------------------------------------
+    /// Sets the disable ASLR flag to \a enable for a process that will 
+    /// be launched with the 'A' packet.
+    ///
+    /// @param[in] enable
+    ///     A boolean value indicating wether to disable ASLR or not.
+    ///
+    /// @return
+    ///     Zero if the for success, or an error code for failure.
+    //------------------------------------------------------------------
+    int
+    SetDisableASLR (bool enable);
+
+    //------------------------------------------------------------------
+    /// Sets the working directory to \a path for a process that will 
+    /// be launched with the 'A' packet.
+    ///
+    /// @param[in] path
+    ///     The path to a directory to use when launching our processs
+    ///
+    /// @return
+    ///     Zero if the for success, or an error code for failure.
+    //------------------------------------------------------------------
+    int
+    SetWorkingDir (char const *path);
+
+    lldb::addr_t
+    AllocateMemory (size_t size, uint32_t permissions);
+
+    bool
+    DeallocateMemory (lldb::addr_t addr);
+
+    const lldb_private::ArchSpec &
+    GetHostArchitecture ();
+    
+    const lldb_private::ConstString &
+    GetOSString ();
+    
+    const lldb_private::ConstString &
+    GetVendorString();
+    
+    lldb::ByteOrder
+    GetByteOrder ();
+
+    uint32_t
+    GetAddressByteSize ();
+
+    bool
+    GetVContSupported (char flavor);
+
+    void
+    ResetDiscoverableSettings();
+
+    bool
+    GetHostInfo ();
+    
+    bool
+    GetSupportsThreadSuffix ();
+
+    bool
+    HasFullVContSupport ()
+    {
+        return GetVContSupported ('A');
+    }
+
+    bool
+    HasAnyVContSupport ()
+    {
+        return GetVContSupported ('a');
+    }
+    
+    uint32_t 
+    SetPacketTimeout (uint32_t packet_timeout)
+    {
+        const uint32_t old_packet_timeout = m_packet_timeout;
+        m_packet_timeout = packet_timeout;
+        return old_packet_timeout;
+    }
+
+protected:
+
+    bool
+    HostInfoIsValid () const
+    {
+        return m_supports_qHostInfo != lldb::eLazyBoolCalculate;
+    }
+
+    //------------------------------------------------------------------
+    // Classes that inherit from GDBRemoteCommunicationClient can see and modify these
+    //------------------------------------------------------------------
+    lldb::LazyBool m_supports_not_sending_acks;
+    lldb::LazyBool m_supports_thread_suffix;
+    lldb::LazyBool m_supports_qHostInfo;
+    lldb::LazyBool m_supports_vCont_all;
+    lldb::LazyBool m_supports_vCont_any;
+    lldb::LazyBool m_supports_vCont_c;
+    lldb::LazyBool m_supports_vCont_C;
+    lldb::LazyBool m_supports_vCont_s;
+    lldb::LazyBool m_supports_vCont_S;
+
+    // If we need to send a packet while the target is running, the m_async_XXX
+    // member variables take care of making this happen.
+    lldb_private::Mutex m_async_mutex;
+    lldb_private::Predicate<bool> m_async_packet_predicate;
+    std::string m_async_packet;
+    StringExtractorGDBRemote m_async_response;
+    int m_async_signal; // We were asked to deliver a signal to the inferior process.
+    
+    lldb_private::ArchSpec m_arch;
+    uint32_t m_cpusubtype;
+    lldb_private::ConstString m_os;
+    lldb_private::ConstString m_vendor;
+    lldb::ByteOrder m_byte_order;
+    uint32_t m_pointer_byte_size;
+
+
+    
+private:
+    //------------------------------------------------------------------
+    // For GDBRemoteCommunicationClient only
+    //------------------------------------------------------------------
+    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationClient);
+};
+
+#endif  // liblldb_GDBRemoteCommunicationClient_h_

Added: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=128070&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (added)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Mon Mar 21 23:00:09 2011
@@ -0,0 +1,134 @@
+//===-- GDBRemoteCommunicationServer.cpp ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "GDBRemoteCommunicationServer.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/Triple.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/ConnectionFileDescriptor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/TimeValue.h"
+
+// Project includes
+#include "Utility/StringExtractorGDBRemote.h"
+#include "ProcessGDBRemote.h"
+#include "ProcessGDBRemoteLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// GDBRemoteCommunicationServer constructor
+//----------------------------------------------------------------------
+GDBRemoteCommunicationServer::GDBRemoteCommunicationServer() :
+    GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet"),
+    m_async_thread (LLDB_INVALID_HOST_THREAD),
+    m_send_acks (true)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
+{
+}
+
+
+//void *
+//GDBRemoteCommunicationServer::AsyncThread (void *arg)
+//{
+//    GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg;
+//
+//    LogSP log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+//    if (log)
+//        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
+//
+//    StringExtractorGDBRemote packet;
+//    
+//    while ()
+//    {
+//        if (packet.
+//    }
+//
+//    if (log)
+//        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
+//
+//    process->m_async_thread = LLDB_INVALID_HOST_THREAD;
+//    return NULL;
+//}
+//
+bool
+GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout_time_ptr)
+{
+    StringExtractorGDBRemote packet;
+    if (WaitForPacketNoLock (packet, timeout_time_ptr))
+    {
+        const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
+        switch (packet_type)
+        {
+        case StringExtractorGDBRemote::eServerPacketType_nack:
+        case StringExtractorGDBRemote::eServerPacketType_ack:
+            break;
+
+        case StringExtractorGDBRemote::eServerPacketType_invalid:
+        case StringExtractorGDBRemote::eServerPacketType_unimplemented:
+            return SendUnimplementedResponse () > 0;
+
+        case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
+            return Handle_qHostInfo ();
+        }
+        return true;
+    }
+    return false;
+}
+
+size_t
+GDBRemoteCommunicationServer::SendUnimplementedResponse ()
+{
+    return SendPacket ("");
+}
+
+
+bool
+GDBRemoteCommunicationServer::Handle_qHostInfo ()
+{
+    StreamString response;
+    
+    // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
+
+    ArchSpec host_arch (Host::GetArchitecture ());
+    
+    const llvm::Triple &host_triple = host_arch.GetTriple();
+    const llvm::StringRef arch_name (host_triple.getArchName());
+    const llvm::StringRef vendor_name (host_triple.getOSName());
+    const llvm::StringRef os_name (host_triple.getVendorName());
+    response.Printf ("arch:%.*s;ostype:%.*s;vendor:%.*s;ptrsize:%u", 
+                     (int)arch_name.size(), arch_name.data(),
+                     (int)os_name.size(), os_name.data(),
+                     (int)vendor_name.size(), vendor_name.data(),
+                     host_arch.GetAddressByteSize());
+
+    switch (lldb::endian::InlHostByteOrder())
+    {
+    case eByteOrderBig:     response.PutCString ("endian:big;"); break;
+    case eByteOrderLittle:  response.PutCString ("endian:little;"); break;
+    case eByteOrderPDP:     response.PutCString ("endian:pdp;"); break;
+    default:                response.PutCString ("endian:unknown;"); break;
+    }
+    
+    return SendPacket (response.GetString().c_str(),response.GetString().size()) > 0;
+}

Added: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h?rev=128070&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h (added)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h Mon Mar 21 23:00:09 2011
@@ -0,0 +1,69 @@
+//===-- GDBRemoteCommunicationServer.h --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_GDBRemoteCommunicationServer_h_
+#define liblldb_GDBRemoteCommunicationServer_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "GDBRemoteCommunication.h"
+
+class ProcessGDBRemote;
+
+class GDBRemoteCommunicationServer : public GDBRemoteCommunication
+{
+public:
+    enum
+    {
+        eBroadcastBitRunPacketSent = kLoUserBroadcastBit
+    };
+    //------------------------------------------------------------------
+    // Constructors and Destructors
+    //------------------------------------------------------------------
+    GDBRemoteCommunicationServer();
+
+    virtual
+    ~GDBRemoteCommunicationServer();
+
+    bool
+    GetPacketAndSendResponse (const lldb_private::TimeValue* timeout_time_ptr);
+
+    virtual bool
+    GetThreadSuffixSupported ()
+    {
+        return true;
+    }
+
+    virtual bool
+    GetSendAcks ()
+    {
+        return m_send_acks;
+    }
+
+protected:
+    lldb::thread_t m_async_thread;
+    bool m_send_acks;
+
+    size_t
+    SendUnimplementedResponse ();
+
+
+    bool
+    Handle_qHostInfo ();
+
+private:
+    //------------------------------------------------------------------
+    // For GDBRemoteCommunicationServer only
+    //------------------------------------------------------------------
+    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServer);
+};
+
+#endif  // liblldb_GDBRemoteCommunicationServer_h_

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp Mon Mar 21 23:00:09 2011
@@ -208,7 +208,7 @@
 bool
 GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data)
 {
-    GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote();
+    GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
 
     InvalidateIfNeeded(false);
 
@@ -235,7 +235,7 @@
                     assert (packet_len < (sizeof(packet) - 1));
                     if (gdb_comm.SendPacketAndWaitForResponse(packet, response, false))
                     {
-                        if (response.IsNormalPacket())
+                        if (response.IsNormalResponse())
                             if (response.GetHexBytes ((void *)m_reg_data.GetDataStart(), m_reg_data.GetByteSize(), '\xcc') == m_reg_data.GetByteSize())
                                 SetAllRegisterValid (true);
                     }
@@ -290,7 +290,7 @@
 bool
 GDBRemoteRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset)
 {
-    GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote();
+    GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
 // FIXME: This check isn't right because IsRunning checks the Public state, but this
 // is work you need to do - for instance in ShouldStop & friends - before the public 
 // state has been changed.
@@ -358,7 +358,7 @@
                                                               false))
                     {
                         SetAllRegisterValid (false);
-                        if (response.IsOKPacket())
+                        if (response.IsOKResponse())
                         {
                             return true;
                         }
@@ -383,7 +383,7 @@
                                                               response,
                                                               false))
                     {
-                        if (response.IsOKPacket())
+                        if (response.IsOKResponse())
                         {
                             return true;
                         }
@@ -399,7 +399,7 @@
 bool
 GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
 {
-    GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote();
+    GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
     StringExtractorGDBRemote response;
     
     Mutex::Locker locker;
@@ -418,7 +418,7 @@
 
             if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
             {
-                if (response.IsErrorPacket())
+                if (response.IsErrorResponse())
                     return false;
                 
                 response.GetStringRef().insert(0, 1, 'G');
@@ -443,7 +443,7 @@
     if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
         return false;
 
-    GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote();
+    GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
     StringExtractorGDBRemote response;
     Mutex::Locker locker;
     if (gdb_comm.GetSequenceMutex (locker))
@@ -456,7 +456,7 @@
                                                       response, 
                                                       false))
             {
-                if (response.IsOKPacket())
+                if (response.IsOKResponse())
                     return true;
             }
         }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Mon Mar 21 23:00:09 2011
@@ -170,18 +170,20 @@
 
     char packet[128];
     m_register_info.Clear();
-    StringExtractorGDBRemote::Type packet_type = StringExtractorGDBRemote::eResponse;
     uint32_t reg_offset = 0;
     uint32_t reg_num = 0;
-    for (; packet_type == StringExtractorGDBRemote::eResponse; ++reg_num)
+    StringExtractorGDBRemote::ResponseType response_type;
+    for (response_type = StringExtractorGDBRemote::eResponse; 
+         response_type == StringExtractorGDBRemote::eResponse; 
+         ++reg_num)
     {
         const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num);
         assert (packet_len < sizeof(packet));
         StringExtractorGDBRemote response;
         if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
         {
-            packet_type = response.GetType();
-            if (packet_type == StringExtractorGDBRemote::eResponse)
+            response_type = response.GetResponseType();
+            if (response_type == StringExtractorGDBRemote::eResponse)
             {
                 std::string name;
                 std::string value;
@@ -298,7 +300,7 @@
         }
         else
         {
-            packet_type = StringExtractorGDBRemote::eError;
+            response_type = StringExtractorGDBRemote::eError;
         }
     }
 
@@ -1044,7 +1046,7 @@
         Error err;
         StringExtractorGDBRemote response;
         for (m_gdb_comm.SendPacketAndWaitForResponse("qfThreadInfo", response, false);
-             response.IsNormalPacket();
+             response.IsNormalResponse();
              m_gdb_comm.SendPacketAndWaitForResponse("qsThreadInfo", response, false))
         {
             char ch = response.GetChar();
@@ -1460,7 +1462,7 @@
         StringExtractorGDBRemote response;
         if (m_gdb_comm.SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false))
         {
-            if (response.IsNormalPacket())
+            if (response.IsNormalResponse())
                 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
         }
     }
@@ -1487,14 +1489,14 @@
     StringExtractorGDBRemote response;
     if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
     {
-        if (response.IsNormalPacket())
+        if (response.IsNormalResponse())
         {
             error.Clear();
             return response.GetHexBytes(buf, size, '\xdd');
         }
-        else if (response.IsErrorPacket())
+        else if (response.IsErrorResponse())
             error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
-        else if (response.IsUnsupportedPacket())
+        else if (response.IsUnsupportedResponse())
             error.SetErrorStringWithFormat("'%s' packet unsupported", packet);
         else
             error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet, response.GetStringRef().c_str());
@@ -1515,14 +1517,14 @@
     StringExtractorGDBRemote response;
     if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true))
     {
-        if (response.IsOKPacket())
+        if (response.IsOKResponse())
         {
             error.Clear();
             return size;
         }
-        else if (response.IsErrorPacket())
+        else if (response.IsErrorResponse())
             error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
-        else if (response.IsUnsupportedPacket())
+        else if (response.IsUnsupportedResponse())
             error.SetErrorStringWithFormat("'%s' packet unsupported", packet.GetString().c_str());
         else
             error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
@@ -1640,13 +1642,13 @@
             StringExtractorGDBRemote response;
             if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
             {
-                if (response.IsUnsupportedPacket())
+                if (response.IsUnsupportedResponse())
                 {
                     // Disable z packet support and try again
                     m_z0_supported = 0;
                     return EnableBreakpoint (bp_site);
                 }
-                else if (response.IsOKPacket())
+                else if (response.IsOKResponse())
                 {
                     bp_site->SetEnabled(true);
                     bp_site->SetType (BreakpointSite::eExternal);
@@ -1708,11 +1710,11 @@
                 StringExtractorGDBRemote response;
                 if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
                 {
-                    if (response.IsUnsupportedPacket())
+                    if (response.IsUnsupportedResponse())
                     {
                         error.SetErrorString("Breakpoint site was set with Z packet, yet remote debugserver states z packets are not supported.");
                     }
-                    else if (response.IsOKPacket())
+                    else if (response.IsOKResponse())
                     {
                         if (log)
                             log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS", site_id, (uint64_t)addr);
@@ -2121,7 +2123,7 @@
     StringExtractorGDBRemote response;
     if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
     {
-        if (response.IsOKPacket())
+        if (response.IsOKResponse())
         {
             m_curr_tid = tid;
             return true;
@@ -2147,7 +2149,7 @@
     StringExtractorGDBRemote response;
     if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
     {
-        if (response.IsOKPacket())
+        if (response.IsOKResponse())
         {
             m_curr_tid_run = tid;
             return true;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Mon Mar 21 23:00:09 2011
@@ -27,7 +27,7 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Thread.h"
 
-#include "GDBRemoteCommunication.h"
+#include "GDBRemoteCommunicationClient.h"
 #include "Utility/StringExtractor.h"
 #include "GDBRemoteRegisterContext.h"
 
@@ -212,7 +212,7 @@
 
 protected:
     friend class ThreadGDBRemote;
-    friend class GDBRemoteCommunication;
+    friend class GDBRemoteCommunicationClient;
     friend class GDBRemoteRegisterContext;
 
     bool
@@ -289,7 +289,7 @@
     void
     BuildDynamicRegisterInfo (bool force);
 
-    GDBRemoteCommunication &
+    GDBRemoteCommunicationClient &
     GetGDBRemote()
     {
         return m_gdb_comm;
@@ -306,7 +306,7 @@
 
     lldb_private::Flags m_flags;            // Process specific flags (see eFlags enums)
     lldb_private::Mutex m_stdio_mutex;      // Multithreaded protection for stdio
-    GDBRemoteCommunication m_gdb_comm;
+    GDBRemoteCommunicationClient m_gdb_comm;
     lldb::pid_t m_debugserver_pid;
     lldb::thread_t m_debugserver_thread;
     StringExtractor m_last_stop_packet;

Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp Mon Mar 21 23:00:09 2011
@@ -16,8 +16,8 @@
 
 
 
-StringExtractorGDBRemote::Type
-StringExtractorGDBRemote::GetType () const
+StringExtractorGDBRemote::ResponseType
+StringExtractorGDBRemote::GetResponseType () const
 {
     if (m_packet.empty())
         return eUnsupported;
@@ -49,29 +49,57 @@
     return eResponse;
 }
 
+StringExtractorGDBRemote::ServerPacketType
+StringExtractorGDBRemote::GetServerPacketType () const
+{
+    // Empty is not a supported packet...
+    if (m_packet.empty())
+        return eServerPacketType_invalid;
+
+    const char *packet_cstr = m_packet.c_str();
+    switch (m_packet[0])
+    {
+    case '-':
+        if (m_packet.size() == 1)
+            return eServerPacketType_nack;
+        break;
+
+    case '+':
+        if (m_packet.size() == 1)
+            return eServerPacketType_ack;
+        break;
+
+    case 'q':
+        if (strcmp (packet_cstr, "qHostInfo") == 0)
+            return eServerPacketType_qHostInfo;
+        break;
+    }
+    return eServerPacketType_unimplemented;
+}
+
 bool
-StringExtractorGDBRemote::IsOKPacket() const
+StringExtractorGDBRemote::IsOKResponse() const
 {
-    return GetType () == eOK;
+    return GetResponseType () == eOK;
 }
 
 
 bool
-StringExtractorGDBRemote::IsUnsupportedPacket() const
+StringExtractorGDBRemote::IsUnsupportedResponse() const
 {
-    return GetType () == eUnsupported;
+    return GetResponseType () == eUnsupported;
 }
 
 bool
-StringExtractorGDBRemote::IsNormalPacket() const
+StringExtractorGDBRemote::IsNormalResponse() const
 {
-    return GetType () == eResponse;
+    return GetResponseType () == eResponse;
 }
 
 bool
-StringExtractorGDBRemote::IsErrorPacket() const
+StringExtractorGDBRemote::IsErrorResponse() const
 {
-    return GetType () == eError &&
+    return GetResponseType () == eError &&
            m_packet.size() == 3 &&
            isxdigit(m_packet[1]) &&
            isxdigit(m_packet[2]);
@@ -80,7 +108,7 @@
 uint8_t
 StringExtractorGDBRemote::GetError ()
 {
-    if (GetType() == eError)
+    if (GetResponseType() == eError)
     {
         SetFilePos(1);
         return GetHexU8(255);

Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.h?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.h (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.h Mon Mar 21 23:00:09 2011
@@ -39,30 +39,42 @@
     {
     }
 
-    enum Type
+    enum ServerPacketType
+    {
+        eServerPacketType_nack = 0,
+        eServerPacketType_ack,
+        eServerPacketType_invalid,
+        eServerPacketType_unimplemented,
+        eServerPacketType_qHostInfo
+    };
+    
+    ServerPacketType
+    GetServerPacketType () const;
+
+    enum ResponseType
     {
         eUnsupported = 0,
         eAck,
         eNack,
         eError,
         eOK,
-        eResponse
+        eResponse,
     };
 
-    StringExtractorGDBRemote::Type
-    GetType () const;
+    ResponseType
+    GetResponseType () const;
 
     bool
-    IsOKPacket() const;
+    IsOKResponse() const;
 
     bool
-    IsUnsupportedPacket() const;
+    IsUnsupportedResponse() const;
 
     bool
-    IsNormalPacket () const;
+    IsNormalResponse () const;
 
     bool
-    IsErrorPacket() const;
+    IsErrorResponse() const;
 
     // Returns zero if the packet isn't a EXX packet where XX are two hex
     // digits. Otherwise the error encoded in XX is returned.

Modified: lldb/trunk/tools/lldb-platform/lldb-platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-platform/lldb-platform.cpp?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-platform/lldb-platform.cpp (original)
+++ lldb/trunk/tools/lldb-platform/lldb-platform.cpp Mon Mar 21 23:00:09 2011
@@ -15,7 +15,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "GDBRemoteCommunication.h"
+#include "GDBRemoteCommunicationServer.h"
 
 //----------------------------------------------------------------------
 // option descriptors for getopt_long()
@@ -106,7 +106,7 @@
     argv += optind;
 
 
-    GDBRemoteCommunication gdb_comm;
+    GDBRemoteCommunicationServer gdb_comm;
 
     return 0;
 }





More information about the lldb-commits mailing list