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