xref: /llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (revision 1cb6496eb024249cd9b67e9c53808553128dd0e7)
1 //===-- GDBRemoteCommunicationServer.cpp ------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 
11 #include "GDBRemoteCommunicationServer.h"
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 #include "llvm/ADT/Triple.h"
17 #include "lldb/Interpreter/Args.h"
18 #include "lldb/Core/ConnectionFileDescriptor.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/State.h"
21 #include "lldb/Core/StreamString.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Host/TimeValue.h"
24 
25 // Project includes
26 #include "Utility/StringExtractorGDBRemote.h"
27 #include "ProcessGDBRemote.h"
28 #include "ProcessGDBRemoteLog.h"
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 //----------------------------------------------------------------------
34 // GDBRemoteCommunicationServer constructor
35 //----------------------------------------------------------------------
36 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer() :
37     GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet"),
38     m_async_thread (LLDB_INVALID_HOST_THREAD)
39 {
40 }
41 
42 //----------------------------------------------------------------------
43 // Destructor
44 //----------------------------------------------------------------------
45 GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
46 {
47 }
48 
49 
50 //void *
51 //GDBRemoteCommunicationServer::AsyncThread (void *arg)
52 //{
53 //    GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg;
54 //
55 //    LogSP log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
56 //    if (log)
57 //        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
58 //
59 //    StringExtractorGDBRemote packet;
60 //
61 //    while ()
62 //    {
63 //        if (packet.
64 //    }
65 //
66 //    if (log)
67 //        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
68 //
69 //    process->m_async_thread = LLDB_INVALID_HOST_THREAD;
70 //    return NULL;
71 //}
72 //
73 bool
74 GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout_ptr,
75                                                         Error &error,
76                                                         bool &interrupt,
77                                                         bool &quit)
78 {
79     StringExtractorGDBRemote packet;
80     if (WaitForPacketNoLock (packet, timeout_ptr))
81     {
82         const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
83         switch (packet_type)
84         {
85         case StringExtractorGDBRemote::eServerPacketType_nack:
86         case StringExtractorGDBRemote::eServerPacketType_ack:
87             break;
88 
89         case StringExtractorGDBRemote::eServerPacketType_invalid:
90             error.SetErrorString("invalid packet");
91             quit = true;
92             break;
93 
94         case StringExtractorGDBRemote::eServerPacketType_interrupt:
95             error.SetErrorString("interrupt received");
96             interrupt = true;
97             break;
98 
99         case StringExtractorGDBRemote::eServerPacketType_unimplemented:
100             return SendUnimplementedResponse () > 0;
101 
102         case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
103             return Handle_qHostInfo ();
104 
105         case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
106             return Handle_QStartNoAckMode ();
107         }
108         return true;
109     }
110     else
111     {
112         if (!IsConnected())
113             error.SetErrorString("lost connection");
114         else
115             error.SetErrorString("timeout");
116     }
117 
118     return false;
119 }
120 
121 size_t
122 GDBRemoteCommunicationServer::SendUnimplementedResponse ()
123 {
124     return SendPacket ("");
125 }
126 
127 size_t
128 GDBRemoteCommunicationServer::SendOKResponse ()
129 {
130     return SendPacket ("OK");
131 }
132 
133 bool
134 GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
135 {
136     if (StartReadThread(error_ptr))
137         return GetAck();
138     return false;
139 }
140 
141 bool
142 GDBRemoteCommunicationServer::Handle_qHostInfo ()
143 {
144     StreamString response;
145 
146     // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
147 
148     ArchSpec host_arch (Host::GetArchitecture ());
149     const llvm::Triple &host_triple = host_arch.GetTriple();
150     response.PutCString("triple:");
151     response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
152     response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
153 
154     uint32_t cpu = host_arch.GetMachOCPUType();
155     uint32_t sub = host_arch.GetMachOCPUSubType();
156     if (cpu != LLDB_INVALID_CPUTYPE)
157         response.Printf ("cputype:%u;", cpu);
158     if (sub != LLDB_INVALID_CPUTYPE)
159         response.Printf ("cpusubtype:%u;", sub);
160 
161     switch (lldb::endian::InlHostByteOrder())
162     {
163     case eByteOrderBig:     response.PutCString ("endian:big;"); break;
164     case eByteOrderLittle:  response.PutCString ("endian:little;"); break;
165     case eByteOrderPDP:     response.PutCString ("endian:pdp;"); break;
166     default:                response.PutCString ("endian:unknown;"); break;
167     }
168 
169     uint32_t major = UINT32_MAX;
170     uint32_t minor = UINT32_MAX;
171     uint32_t update = UINT32_MAX;
172     if (Host::GetOSVersion (major, minor, update))
173     {
174         if (major != UINT32_MAX)
175         {
176             response.Printf("os_version:%u", major);
177             if (minor != UINT32_MAX)
178             {
179                 response.Printf(".%u", minor);
180                 if (update != UINT32_MAX)
181                     response.Printf(".%u", update);
182             }
183             response.PutChar(';');
184         }
185     }
186 
187     std::string s;
188     if (Host::GetOSBuildString (s))
189     {
190         response.PutCString ("os_build:");
191         response.PutCStringAsRawHex8(s.c_str());
192         response.PutChar(';');
193     }
194     if (Host::GetOSKernelDescription (s))
195     {
196         response.PutCString ("os_kernel:");
197         response.PutCStringAsRawHex8(s.c_str());
198         response.PutChar(';');
199     }
200     if (Host::GetHostname (s))
201     {
202         response.PutCString ("hostname:");
203         response.PutCStringAsRawHex8(s.c_str());
204         response.PutChar(';');
205     }
206 
207     return SendPacket (response.GetString().c_str(),response.GetString().size()) > 0;
208 }
209 
210 
211 bool
212 GDBRemoteCommunicationServer::Handle_QStartNoAckMode ()
213 {
214     SendOKResponse ();
215     m_send_acks = false;
216     return true;
217 }
218