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 #include <errno.h> 11 12 #include "GDBRemoteCommunicationServer.h" 13 #include "lldb/Core/StreamGDBRemote.h" 14 15 // C Includes 16 // C++ Includes 17 // Other libraries and framework includes 18 #include "llvm/ADT/Triple.h" 19 #include "lldb/Interpreter/Args.h" 20 #include "lldb/Core/ConnectionFileDescriptor.h" 21 #include "lldb/Core/Log.h" 22 #include "lldb/Core/State.h" 23 #include "lldb/Core/StreamString.h" 24 #include "lldb/Host/Endian.h" 25 #include "lldb/Host/File.h" 26 #include "lldb/Host/Host.h" 27 #include "lldb/Host/TimeValue.h" 28 #include "lldb/Target/Process.h" 29 30 // Project includes 31 #include "Utility/StringExtractorGDBRemote.h" 32 #include "ProcessGDBRemote.h" 33 #include "ProcessGDBRemoteLog.h" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 38 //---------------------------------------------------------------------- 39 // GDBRemoteCommunicationServer constructor 40 //---------------------------------------------------------------------- 41 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) : 42 GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform), 43 m_async_thread (LLDB_INVALID_HOST_THREAD), 44 m_process_launch_info (), 45 m_process_launch_error (), 46 m_spawned_pids (), 47 m_spawned_pids_mutex (Mutex::eMutexTypeRecursive), 48 m_proc_infos (), 49 m_proc_infos_index (0), 50 m_port_map (), 51 m_port_offset(0) 52 { 53 } 54 55 //---------------------------------------------------------------------- 56 // Destructor 57 //---------------------------------------------------------------------- 58 GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() 59 { 60 } 61 62 63 //void * 64 //GDBRemoteCommunicationServer::AsyncThread (void *arg) 65 //{ 66 // GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg; 67 // 68 // Log *log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 69 // if (log) 70 // log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID()); 71 // 72 // StringExtractorGDBRemote packet; 73 // 74 // while () 75 // { 76 // if (packet. 77 // } 78 // 79 // if (log) 80 // log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID()); 81 // 82 // process->m_async_thread = LLDB_INVALID_HOST_THREAD; 83 // return NULL; 84 //} 85 // 86 bool 87 GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec, 88 Error &error, 89 bool &interrupt, 90 bool &quit) 91 { 92 StringExtractorGDBRemote packet; 93 PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec); 94 if (packet_result == PacketResult::Success) 95 { 96 const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType (); 97 switch (packet_type) 98 { 99 case StringExtractorGDBRemote::eServerPacketType_nack: 100 case StringExtractorGDBRemote::eServerPacketType_ack: 101 break; 102 103 case StringExtractorGDBRemote::eServerPacketType_invalid: 104 error.SetErrorString("invalid packet"); 105 quit = true; 106 break; 107 108 case StringExtractorGDBRemote::eServerPacketType_interrupt: 109 error.SetErrorString("interrupt received"); 110 interrupt = true; 111 break; 112 113 default: 114 case StringExtractorGDBRemote::eServerPacketType_unimplemented: 115 packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str()); 116 break; 117 118 case StringExtractorGDBRemote::eServerPacketType_A: 119 packet_result = Handle_A (packet); 120 break; 121 122 case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo: 123 packet_result = Handle_qfProcessInfo (packet); 124 break; 125 126 case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo: 127 packet_result = Handle_qsProcessInfo (packet); 128 break; 129 130 case StringExtractorGDBRemote::eServerPacketType_qC: 131 packet_result = Handle_qC (packet); 132 break; 133 134 case StringExtractorGDBRemote::eServerPacketType_qHostInfo: 135 packet_result = Handle_qHostInfo (packet); 136 break; 137 138 case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer: 139 packet_result = Handle_qLaunchGDBServer (packet); 140 break; 141 142 case StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess: 143 packet_result = Handle_qKillSpawnedProcess (packet); 144 break; 145 146 case StringExtractorGDBRemote::eServerPacketType_k: 147 packet_result = Handle_k (packet); 148 break; 149 150 case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess: 151 packet_result = Handle_qLaunchSuccess (packet); 152 break; 153 154 case StringExtractorGDBRemote::eServerPacketType_qGroupName: 155 packet_result = Handle_qGroupName (packet); 156 break; 157 158 case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID: 159 packet_result = Handle_qProcessInfoPID (packet); 160 break; 161 162 case StringExtractorGDBRemote::eServerPacketType_qSpeedTest: 163 packet_result = Handle_qSpeedTest (packet); 164 break; 165 166 case StringExtractorGDBRemote::eServerPacketType_qUserName: 167 packet_result = Handle_qUserName (packet); 168 break; 169 170 case StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir: 171 packet_result = Handle_qGetWorkingDir(packet); 172 break; 173 174 case StringExtractorGDBRemote::eServerPacketType_QEnvironment: 175 packet_result = Handle_QEnvironment (packet); 176 break; 177 178 case StringExtractorGDBRemote::eServerPacketType_QLaunchArch: 179 packet_result = Handle_QLaunchArch (packet); 180 break; 181 182 case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR: 183 packet_result = Handle_QSetDisableASLR (packet); 184 break; 185 186 case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN: 187 packet_result = Handle_QSetSTDIN (packet); 188 break; 189 190 case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT: 191 packet_result = Handle_QSetSTDOUT (packet); 192 break; 193 194 case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR: 195 packet_result = Handle_QSetSTDERR (packet); 196 break; 197 198 case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir: 199 packet_result = Handle_QSetWorkingDir (packet); 200 break; 201 202 case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode: 203 packet_result = Handle_QStartNoAckMode (packet); 204 break; 205 206 case StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir: 207 packet_result = Handle_qPlatform_mkdir (packet); 208 break; 209 210 case StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod: 211 packet_result = Handle_qPlatform_chmod (packet); 212 break; 213 214 case StringExtractorGDBRemote::eServerPacketType_qPlatform_shell: 215 packet_result = Handle_qPlatform_shell (packet); 216 break; 217 218 case StringExtractorGDBRemote::eServerPacketType_vFile_open: 219 packet_result = Handle_vFile_Open (packet); 220 break; 221 222 case StringExtractorGDBRemote::eServerPacketType_vFile_close: 223 packet_result = Handle_vFile_Close (packet); 224 break; 225 226 case StringExtractorGDBRemote::eServerPacketType_vFile_pread: 227 packet_result = Handle_vFile_pRead (packet); 228 break; 229 230 case StringExtractorGDBRemote::eServerPacketType_vFile_pwrite: 231 packet_result = Handle_vFile_pWrite (packet); 232 break; 233 234 case StringExtractorGDBRemote::eServerPacketType_vFile_size: 235 packet_result = Handle_vFile_Size (packet); 236 break; 237 238 case StringExtractorGDBRemote::eServerPacketType_vFile_mode: 239 packet_result = Handle_vFile_Mode (packet); 240 break; 241 242 case StringExtractorGDBRemote::eServerPacketType_vFile_exists: 243 packet_result = Handle_vFile_Exists (packet); 244 break; 245 246 case StringExtractorGDBRemote::eServerPacketType_vFile_stat: 247 packet_result = Handle_vFile_Stat (packet); 248 break; 249 250 case StringExtractorGDBRemote::eServerPacketType_vFile_md5: 251 packet_result = Handle_vFile_MD5 (packet); 252 break; 253 254 case StringExtractorGDBRemote::eServerPacketType_vFile_symlink: 255 packet_result = Handle_vFile_symlink (packet); 256 break; 257 258 case StringExtractorGDBRemote::eServerPacketType_vFile_unlink: 259 packet_result = Handle_vFile_unlink (packet); 260 break; 261 } 262 } 263 else 264 { 265 if (!IsConnected()) 266 { 267 error.SetErrorString("lost connection"); 268 quit = true; 269 } 270 else 271 { 272 error.SetErrorString("timeout"); 273 } 274 } 275 return packet_result == PacketResult::Success; 276 } 277 278 lldb_private::Error 279 GDBRemoteCommunicationServer::SetLaunchArguments (const char *const args[], int argc) 280 { 281 if ((argc < 1) || !args || !args[0] || !args[0][0]) 282 return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__); 283 284 m_process_launch_info.SetArguments (const_cast<const char**> (args), true); 285 return lldb_private::Error (); 286 } 287 288 lldb_private::Error 289 GDBRemoteCommunicationServer::SetLaunchFlags (unsigned int launch_flags) 290 { 291 m_process_launch_info.GetFlags ().Set (launch_flags); 292 return lldb_private::Error (); 293 } 294 295 lldb_private::Error 296 GDBRemoteCommunicationServer::LaunchProcess () 297 { 298 if (!m_process_launch_info.GetArguments ().GetArgumentCount ()) 299 return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__); 300 301 // specify the process monitor if not already set. This should 302 // generally be what happens since we need to reap started 303 // processes. 304 if (!m_process_launch_info.GetMonitorProcessCallback ()) 305 m_process_launch_info.SetMonitorProcessCallback(ReapDebuggedProcess, this, false); 306 307 lldb_private::Error error = Host::LaunchProcess (m_process_launch_info); 308 if (!error.Success ()) 309 { 310 fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0)); 311 return error; 312 } 313 314 printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID()); 315 316 // add to list of spawned processes. On an lldb-gdbserver, we 317 // would expect there to be only one. 318 lldb::pid_t pid; 319 if ( (pid = m_process_launch_info.GetProcessID()) != LLDB_INVALID_PROCESS_ID ) 320 { 321 Mutex::Locker locker (m_spawned_pids_mutex); 322 m_spawned_pids.insert(pid); 323 } 324 325 return error; 326 } 327 328 GDBRemoteCommunication::PacketResult 329 GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *) 330 { 331 // TODO: Log the packet we aren't handling... 332 return SendPacketNoLock ("", 0); 333 } 334 335 GDBRemoteCommunication::PacketResult 336 GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err) 337 { 338 char packet[16]; 339 int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err); 340 assert (packet_len < (int)sizeof(packet)); 341 return SendPacketNoLock (packet, packet_len); 342 } 343 344 345 GDBRemoteCommunication::PacketResult 346 GDBRemoteCommunicationServer::SendOKResponse () 347 { 348 return SendPacketNoLock ("OK", 2); 349 } 350 351 bool 352 GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) 353 { 354 return GetAck() == PacketResult::Success; 355 } 356 357 GDBRemoteCommunication::PacketResult 358 GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet) 359 { 360 StreamString response; 361 362 // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 363 364 ArchSpec host_arch (Host::GetArchitecture ()); 365 const llvm::Triple &host_triple = host_arch.GetTriple(); 366 response.PutCString("triple:"); 367 response.PutCStringAsRawHex8(host_triple.getTriple().c_str()); 368 response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize()); 369 370 const char* distribution_id = host_arch.GetDistributionId ().AsCString (); 371 if (distribution_id) 372 { 373 response.PutCString("distribution_id:"); 374 response.PutCStringAsRawHex8(distribution_id); 375 response.PutCString(";"); 376 } 377 378 uint32_t cpu = host_arch.GetMachOCPUType(); 379 uint32_t sub = host_arch.GetMachOCPUSubType(); 380 if (cpu != LLDB_INVALID_CPUTYPE) 381 response.Printf ("cputype:%u;", cpu); 382 if (sub != LLDB_INVALID_CPUTYPE) 383 response.Printf ("cpusubtype:%u;", sub); 384 385 if (cpu == ArchSpec::kCore_arm_any) 386 response.Printf("watchpoint_exceptions_received:before;"); // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 387 else 388 response.Printf("watchpoint_exceptions_received:after;"); 389 390 switch (lldb::endian::InlHostByteOrder()) 391 { 392 case eByteOrderBig: response.PutCString ("endian:big;"); break; 393 case eByteOrderLittle: response.PutCString ("endian:little;"); break; 394 case eByteOrderPDP: response.PutCString ("endian:pdp;"); break; 395 default: response.PutCString ("endian:unknown;"); break; 396 } 397 398 uint32_t major = UINT32_MAX; 399 uint32_t minor = UINT32_MAX; 400 uint32_t update = UINT32_MAX; 401 if (Host::GetOSVersion (major, minor, update)) 402 { 403 if (major != UINT32_MAX) 404 { 405 response.Printf("os_version:%u", major); 406 if (minor != UINT32_MAX) 407 { 408 response.Printf(".%u", minor); 409 if (update != UINT32_MAX) 410 response.Printf(".%u", update); 411 } 412 response.PutChar(';'); 413 } 414 } 415 416 std::string s; 417 if (Host::GetOSBuildString (s)) 418 { 419 response.PutCString ("os_build:"); 420 response.PutCStringAsRawHex8(s.c_str()); 421 response.PutChar(';'); 422 } 423 if (Host::GetOSKernelDescription (s)) 424 { 425 response.PutCString ("os_kernel:"); 426 response.PutCStringAsRawHex8(s.c_str()); 427 response.PutChar(';'); 428 } 429 #if defined(__APPLE__) 430 431 #if defined(__arm__) 432 // For iOS devices, we are connected through a USB Mux so we never pretend 433 // to actually have a hostname as far as the remote lldb that is connecting 434 // to this lldb-platform is concerned 435 response.PutCString ("hostname:"); 436 response.PutCStringAsRawHex8("localhost"); 437 response.PutChar(';'); 438 #else // #if defined(__arm__) 439 if (Host::GetHostname (s)) 440 { 441 response.PutCString ("hostname:"); 442 response.PutCStringAsRawHex8(s.c_str()); 443 response.PutChar(';'); 444 } 445 446 #endif // #if defined(__arm__) 447 448 #else // #if defined(__APPLE__) 449 if (Host::GetHostname (s)) 450 { 451 response.PutCString ("hostname:"); 452 response.PutCStringAsRawHex8(s.c_str()); 453 response.PutChar(';'); 454 } 455 #endif // #if defined(__APPLE__) 456 457 return SendPacketNoLock (response.GetData(), response.GetSize()); 458 } 459 460 static void 461 CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response) 462 { 463 response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;", 464 proc_info.GetProcessID(), 465 proc_info.GetParentProcessID(), 466 proc_info.GetUserID(), 467 proc_info.GetGroupID(), 468 proc_info.GetEffectiveUserID(), 469 proc_info.GetEffectiveGroupID()); 470 response.PutCString ("name:"); 471 response.PutCStringAsRawHex8(proc_info.GetName()); 472 response.PutChar(';'); 473 const ArchSpec &proc_arch = proc_info.GetArchitecture(); 474 if (proc_arch.IsValid()) 475 { 476 const llvm::Triple &proc_triple = proc_arch.GetTriple(); 477 response.PutCString("triple:"); 478 response.PutCStringAsRawHex8(proc_triple.getTriple().c_str()); 479 response.PutChar(';'); 480 } 481 } 482 483 GDBRemoteCommunication::PacketResult 484 GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet) 485 { 486 // Packet format: "qProcessInfoPID:%i" where %i is the pid 487 packet.SetFilePos(::strlen ("qProcessInfoPID:")); 488 lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID); 489 if (pid != LLDB_INVALID_PROCESS_ID) 490 { 491 ProcessInstanceInfo proc_info; 492 if (Host::GetProcessInfo(pid, proc_info)) 493 { 494 StreamString response; 495 CreateProcessInfoResponse (proc_info, response); 496 return SendPacketNoLock (response.GetData(), response.GetSize()); 497 } 498 } 499 return SendErrorResponse (1); 500 } 501 502 GDBRemoteCommunication::PacketResult 503 GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet) 504 { 505 m_proc_infos_index = 0; 506 m_proc_infos.Clear(); 507 508 ProcessInstanceInfoMatch match_info; 509 packet.SetFilePos(::strlen ("qfProcessInfo")); 510 if (packet.GetChar() == ':') 511 { 512 513 std::string key; 514 std::string value; 515 while (packet.GetNameColonValue(key, value)) 516 { 517 bool success = true; 518 if (key.compare("name") == 0) 519 { 520 StringExtractor extractor; 521 extractor.GetStringRef().swap(value); 522 extractor.GetHexByteString (value); 523 match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false); 524 } 525 else if (key.compare("name_match") == 0) 526 { 527 if (value.compare("equals") == 0) 528 { 529 match_info.SetNameMatchType (eNameMatchEquals); 530 } 531 else if (value.compare("starts_with") == 0) 532 { 533 match_info.SetNameMatchType (eNameMatchStartsWith); 534 } 535 else if (value.compare("ends_with") == 0) 536 { 537 match_info.SetNameMatchType (eNameMatchEndsWith); 538 } 539 else if (value.compare("contains") == 0) 540 { 541 match_info.SetNameMatchType (eNameMatchContains); 542 } 543 else if (value.compare("regex") == 0) 544 { 545 match_info.SetNameMatchType (eNameMatchRegularExpression); 546 } 547 else 548 { 549 success = false; 550 } 551 } 552 else if (key.compare("pid") == 0) 553 { 554 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); 555 } 556 else if (key.compare("parent_pid") == 0) 557 { 558 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); 559 } 560 else if (key.compare("uid") == 0) 561 { 562 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 563 } 564 else if (key.compare("gid") == 0) 565 { 566 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 567 } 568 else if (key.compare("euid") == 0) 569 { 570 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 571 } 572 else if (key.compare("egid") == 0) 573 { 574 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 575 } 576 else if (key.compare("all_users") == 0) 577 { 578 match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success)); 579 } 580 else if (key.compare("triple") == 0) 581 { 582 match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL); 583 } 584 else 585 { 586 success = false; 587 } 588 589 if (!success) 590 return SendErrorResponse (2); 591 } 592 } 593 594 if (Host::FindProcesses (match_info, m_proc_infos)) 595 { 596 // We found something, return the first item by calling the get 597 // subsequent process info packet handler... 598 return Handle_qsProcessInfo (packet); 599 } 600 return SendErrorResponse (3); 601 } 602 603 GDBRemoteCommunication::PacketResult 604 GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet) 605 { 606 if (m_proc_infos_index < m_proc_infos.GetSize()) 607 { 608 StreamString response; 609 CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response); 610 ++m_proc_infos_index; 611 return SendPacketNoLock (response.GetData(), response.GetSize()); 612 } 613 return SendErrorResponse (4); 614 } 615 616 GDBRemoteCommunication::PacketResult 617 GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet) 618 { 619 // Packet format: "qUserName:%i" where %i is the uid 620 packet.SetFilePos(::strlen ("qUserName:")); 621 uint32_t uid = packet.GetU32 (UINT32_MAX); 622 if (uid != UINT32_MAX) 623 { 624 std::string name; 625 if (Host::GetUserName (uid, name)) 626 { 627 StreamString response; 628 response.PutCStringAsRawHex8 (name.c_str()); 629 return SendPacketNoLock (response.GetData(), response.GetSize()); 630 } 631 } 632 return SendErrorResponse (5); 633 634 } 635 636 GDBRemoteCommunication::PacketResult 637 GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet) 638 { 639 // Packet format: "qGroupName:%i" where %i is the gid 640 packet.SetFilePos(::strlen ("qGroupName:")); 641 uint32_t gid = packet.GetU32 (UINT32_MAX); 642 if (gid != UINT32_MAX) 643 { 644 std::string name; 645 if (Host::GetGroupName (gid, name)) 646 { 647 StreamString response; 648 response.PutCStringAsRawHex8 (name.c_str()); 649 return SendPacketNoLock (response.GetData(), response.GetSize()); 650 } 651 } 652 return SendErrorResponse (6); 653 } 654 655 GDBRemoteCommunication::PacketResult 656 GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet) 657 { 658 packet.SetFilePos(::strlen ("qSpeedTest:")); 659 660 std::string key; 661 std::string value; 662 bool success = packet.GetNameColonValue(key, value); 663 if (success && key.compare("response_size") == 0) 664 { 665 uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success); 666 if (success) 667 { 668 if (response_size == 0) 669 return SendOKResponse(); 670 StreamString response; 671 uint32_t bytes_left = response_size; 672 response.PutCString("data:"); 673 while (bytes_left > 0) 674 { 675 if (bytes_left >= 26) 676 { 677 response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 678 bytes_left -= 26; 679 } 680 else 681 { 682 response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 683 bytes_left = 0; 684 } 685 } 686 return SendPacketNoLock (response.GetData(), response.GetSize()); 687 } 688 } 689 return SendErrorResponse (7); 690 } 691 692 693 static void * 694 AcceptPortFromInferior (void *arg) 695 { 696 const char *connect_url = (const char *)arg; 697 ConnectionFileDescriptor file_conn; 698 Error error; 699 if (file_conn.Connect (connect_url, &error) == eConnectionStatusSuccess) 700 { 701 char pid_str[256]; 702 ::memset (pid_str, 0, sizeof(pid_str)); 703 ConnectionStatus status; 704 const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), 0, status, NULL); 705 if (pid_str_len > 0) 706 { 707 int pid = atoi (pid_str); 708 return (void *)(intptr_t)pid; 709 } 710 } 711 return NULL; 712 } 713 // 714 //static bool 715 //WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) 716 //{ 717 // const int time_delta_usecs = 100000; 718 // const int num_retries = timeout_in_seconds/time_delta_usecs; 719 // for (int i=0; i<num_retries; i++) 720 // { 721 // struct proc_bsdinfo bsd_info; 722 // int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO, 723 // (uint64_t) 0, 724 // &bsd_info, 725 // PROC_PIDTBSDINFO_SIZE); 726 // 727 // switch (error) 728 // { 729 // case EINVAL: 730 // case ENOTSUP: 731 // case ESRCH: 732 // case EPERM: 733 // return false; 734 // 735 // default: 736 // break; 737 // 738 // case 0: 739 // if (bsd_info.pbi_status == SSTOP) 740 // return true; 741 // } 742 // ::usleep (time_delta_usecs); 743 // } 744 // return false; 745 //} 746 747 GDBRemoteCommunication::PacketResult 748 GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet) 749 { 750 // The 'A' packet is the most over designed packet ever here with 751 // redundant argument indexes, redundant argument lengths and needed hex 752 // encoded argument string values. Really all that is needed is a comma 753 // separated hex encoded argument value list, but we will stay true to the 754 // documented version of the 'A' packet here... 755 756 packet.SetFilePos(1); // Skip the 'A' 757 bool success = true; 758 while (success && packet.GetBytesLeft() > 0) 759 { 760 // Decode the decimal argument string length. This length is the 761 // number of hex nibbles in the argument string value. 762 const uint32_t arg_len = packet.GetU32(UINT32_MAX); 763 if (arg_len == UINT32_MAX) 764 success = false; 765 else 766 { 767 // Make sure the argument hex string length is followed by a comma 768 if (packet.GetChar() != ',') 769 success = false; 770 else 771 { 772 // Decode the argument index. We ignore this really becuase 773 // who would really send down the arguments in a random order??? 774 const uint32_t arg_idx = packet.GetU32(UINT32_MAX); 775 if (arg_idx == UINT32_MAX) 776 success = false; 777 else 778 { 779 // Make sure the argument index is followed by a comma 780 if (packet.GetChar() != ',') 781 success = false; 782 else 783 { 784 // Decode the argument string value from hex bytes 785 // back into a UTF8 string and make sure the length 786 // matches the one supplied in the packet 787 std::string arg; 788 if (packet.GetHexByteString(arg) != (arg_len / 2)) 789 success = false; 790 else 791 { 792 // If there are any bytes lft 793 if (packet.GetBytesLeft()) 794 { 795 if (packet.GetChar() != ',') 796 success = false; 797 } 798 799 if (success) 800 { 801 if (arg_idx == 0) 802 m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false); 803 m_process_launch_info.GetArguments().AppendArgument(arg.c_str()); 804 } 805 } 806 } 807 } 808 } 809 } 810 } 811 812 if (success) 813 { 814 m_process_launch_info.GetFlags().Set (eLaunchFlagDebug); 815 m_process_launch_error = Host::LaunchProcess (m_process_launch_info); 816 if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 817 { 818 return SendOKResponse (); 819 } 820 } 821 return SendErrorResponse (8); 822 } 823 824 GDBRemoteCommunication::PacketResult 825 GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet) 826 { 827 lldb::pid_t pid = m_process_launch_info.GetProcessID(); 828 StreamString response; 829 response.Printf("QC%" PRIx64, pid); 830 if (m_is_platform) 831 { 832 // If we launch a process and this GDB server is acting as a platform, 833 // then we need to clear the process launch state so we can start 834 // launching another process. In order to launch a process a bunch or 835 // packets need to be sent: environment packets, working directory, 836 // disable ASLR, and many more settings. When we launch a process we 837 // then need to know when to clear this information. Currently we are 838 // selecting the 'qC' packet as that packet which seems to make the most 839 // sense. 840 if (pid != LLDB_INVALID_PROCESS_ID) 841 { 842 m_process_launch_info.Clear(); 843 } 844 } 845 return SendPacketNoLock (response.GetData(), response.GetSize()); 846 } 847 848 bool 849 GDBRemoteCommunicationServer::DebugserverProcessReaped (lldb::pid_t pid) 850 { 851 Mutex::Locker locker (m_spawned_pids_mutex); 852 FreePortForProcess(pid); 853 return m_spawned_pids.erase(pid) > 0; 854 } 855 bool 856 GDBRemoteCommunicationServer::ReapDebugserverProcess (void *callback_baton, 857 lldb::pid_t pid, 858 bool exited, 859 int signal, // Zero for no signal 860 int status) // Exit value of process if signal is zero 861 { 862 GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton; 863 server->DebugserverProcessReaped (pid); 864 return true; 865 } 866 867 bool 868 GDBRemoteCommunicationServer::DebuggedProcessReaped (lldb::pid_t pid) 869 { 870 // reap a process that we were debugging (but not debugserver) 871 Mutex::Locker locker (m_spawned_pids_mutex); 872 return m_spawned_pids.erase(pid) > 0; 873 } 874 875 bool 876 GDBRemoteCommunicationServer::ReapDebuggedProcess (void *callback_baton, 877 lldb::pid_t pid, 878 bool exited, 879 int signal, // Zero for no signal 880 int status) // Exit value of process if signal is zero 881 { 882 GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton; 883 server->DebuggedProcessReaped (pid); 884 return true; 885 } 886 887 GDBRemoteCommunication::PacketResult 888 GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet) 889 { 890 #ifdef _WIN32 891 return SendErrorResponse(9); 892 #else 893 // Spawn a local debugserver as a platform so we can then attach or launch 894 // a process... 895 896 if (m_is_platform) 897 { 898 // Sleep and wait a bit for debugserver to start to listen... 899 ConnectionFileDescriptor file_conn; 900 Error error; 901 std::string hostname; 902 // TODO: /tmp/ should not be hardcoded. User might want to override /tmp 903 // with the TMPDIR environnement variable 904 packet.SetFilePos(::strlen ("qLaunchGDBServer;")); 905 std::string name; 906 std::string value; 907 uint16_t port = UINT16_MAX; 908 while (packet.GetNameColonValue(name, value)) 909 { 910 if (name.compare ("host") == 0) 911 hostname.swap(value); 912 else if (name.compare ("port") == 0) 913 port = Args::StringToUInt32(value.c_str(), 0, 0); 914 } 915 if (port == UINT16_MAX) 916 port = GetNextAvailablePort(); 917 918 // Spawn a new thread to accept the port that gets bound after 919 // binding to port 0 (zero). 920 921 if (error.Success()) 922 { 923 // Spawn a debugserver and try to get the port it listens to. 924 ProcessLaunchInfo debugserver_launch_info; 925 if (hostname.empty()) 926 hostname = "localhost"; 927 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 928 if (log) 929 log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port); 930 931 debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); 932 933 error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(), 934 port, 935 debugserver_launch_info, 936 port); 937 938 lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); 939 940 941 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 942 { 943 Mutex::Locker locker (m_spawned_pids_mutex); 944 m_spawned_pids.insert(debugserver_pid); 945 if (port > 0) 946 AssociatePortWithProcess(port, debugserver_pid); 947 } 948 else 949 { 950 if (port > 0) 951 FreePort (port); 952 } 953 954 if (error.Success()) 955 { 956 char response[256]; 957 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset); 958 assert (response_len < sizeof(response)); 959 PacketResult packet_result = SendPacketNoLock (response, response_len); 960 961 if (packet_result != PacketResult::Success) 962 { 963 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 964 ::kill (debugserver_pid, SIGINT); 965 } 966 return packet_result; 967 } 968 } 969 } 970 return SendErrorResponse (9); 971 #endif 972 } 973 974 bool 975 GDBRemoteCommunicationServer::KillSpawnedProcess (lldb::pid_t pid) 976 { 977 // make sure we know about this process 978 { 979 Mutex::Locker locker (m_spawned_pids_mutex); 980 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 981 return false; 982 } 983 984 // first try a SIGTERM (standard kill) 985 Host::Kill (pid, SIGTERM); 986 987 // check if that worked 988 for (size_t i=0; i<10; ++i) 989 { 990 { 991 Mutex::Locker locker (m_spawned_pids_mutex); 992 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 993 { 994 // it is now killed 995 return true; 996 } 997 } 998 usleep (10000); 999 } 1000 1001 // check one more time after the final usleep 1002 { 1003 Mutex::Locker locker (m_spawned_pids_mutex); 1004 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1005 return true; 1006 } 1007 1008 // the launched process still lives. Now try killling it again, 1009 // this time with an unblockable signal. 1010 Host::Kill (pid, SIGKILL); 1011 1012 for (size_t i=0; i<10; ++i) 1013 { 1014 { 1015 Mutex::Locker locker (m_spawned_pids_mutex); 1016 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1017 { 1018 // it is now killed 1019 return true; 1020 } 1021 } 1022 usleep (10000); 1023 } 1024 1025 // check one more time after the final usleep 1026 // Scope for locker 1027 { 1028 Mutex::Locker locker (m_spawned_pids_mutex); 1029 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1030 return true; 1031 } 1032 1033 // no luck - the process still lives 1034 return false; 1035 } 1036 1037 GDBRemoteCommunication::PacketResult 1038 GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet) 1039 { 1040 packet.SetFilePos(::strlen ("qKillSpawnedProcess:")); 1041 1042 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID); 1043 1044 // verify that we know anything about this pid. 1045 // Scope for locker 1046 { 1047 Mutex::Locker locker (m_spawned_pids_mutex); 1048 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1049 { 1050 // not a pid we know about 1051 return SendErrorResponse (10); 1052 } 1053 } 1054 1055 // go ahead and attempt to kill the spawned process 1056 if (KillSpawnedProcess (pid)) 1057 return SendOKResponse (); 1058 else 1059 return SendErrorResponse (11); 1060 } 1061 1062 GDBRemoteCommunication::PacketResult 1063 GDBRemoteCommunicationServer::Handle_k (StringExtractorGDBRemote &packet) 1064 { 1065 // ignore for now if we're lldb_platform 1066 if (m_is_platform) 1067 return SendUnimplementedResponse (packet.GetStringRef().c_str()); 1068 1069 // shutdown all spawned processes 1070 std::set<lldb::pid_t> spawned_pids_copy; 1071 1072 // copy pids 1073 { 1074 Mutex::Locker locker (m_spawned_pids_mutex); 1075 spawned_pids_copy.insert (m_spawned_pids.begin (), m_spawned_pids.end ()); 1076 } 1077 1078 // nuke the spawned processes 1079 for (auto it = spawned_pids_copy.begin (); it != spawned_pids_copy.end (); ++it) 1080 { 1081 lldb::pid_t spawned_pid = *it; 1082 if (!KillSpawnedProcess (spawned_pid)) 1083 { 1084 fprintf (stderr, "%s: failed to kill spawned pid %" PRIu64 ", ignoring.\n", __FUNCTION__, spawned_pid); 1085 } 1086 } 1087 1088 // TODO figure out how to shut down gracefully at this point 1089 return SendOKResponse (); 1090 } 1091 1092 GDBRemoteCommunication::PacketResult 1093 GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet) 1094 { 1095 if (m_process_launch_error.Success()) 1096 return SendOKResponse(); 1097 StreamString response; 1098 response.PutChar('E'); 1099 response.PutCString(m_process_launch_error.AsCString("<unknown error>")); 1100 return SendPacketNoLock (response.GetData(), response.GetSize()); 1101 } 1102 1103 GDBRemoteCommunication::PacketResult 1104 GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &packet) 1105 { 1106 packet.SetFilePos(::strlen ("QEnvironment:")); 1107 const uint32_t bytes_left = packet.GetBytesLeft(); 1108 if (bytes_left > 0) 1109 { 1110 m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek()); 1111 return SendOKResponse (); 1112 } 1113 return SendErrorResponse (12); 1114 } 1115 1116 GDBRemoteCommunication::PacketResult 1117 GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &packet) 1118 { 1119 packet.SetFilePos(::strlen ("QLaunchArch:")); 1120 const uint32_t bytes_left = packet.GetBytesLeft(); 1121 if (bytes_left > 0) 1122 { 1123 const char* arch_triple = packet.Peek(); 1124 ArchSpec arch_spec(arch_triple,NULL); 1125 m_process_launch_info.SetArchitecture(arch_spec); 1126 return SendOKResponse(); 1127 } 1128 return SendErrorResponse(13); 1129 } 1130 1131 GDBRemoteCommunication::PacketResult 1132 GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet) 1133 { 1134 packet.SetFilePos(::strlen ("QSetDisableASLR:")); 1135 if (packet.GetU32(0)) 1136 m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR); 1137 else 1138 m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); 1139 return SendOKResponse (); 1140 } 1141 1142 GDBRemoteCommunication::PacketResult 1143 GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet) 1144 { 1145 packet.SetFilePos(::strlen ("QSetWorkingDir:")); 1146 std::string path; 1147 packet.GetHexByteString(path); 1148 if (m_is_platform) 1149 { 1150 #ifdef _WIN32 1151 // Not implemented on Windows 1152 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_QSetWorkingDir unimplemented"); 1153 #else 1154 // If this packet is sent to a platform, then change the current working directory 1155 if (::chdir(path.c_str()) != 0) 1156 return SendErrorResponse(errno); 1157 #endif 1158 } 1159 else 1160 { 1161 m_process_launch_info.SwapWorkingDirectory (path); 1162 } 1163 return SendOKResponse (); 1164 } 1165 1166 GDBRemoteCommunication::PacketResult 1167 GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet) 1168 { 1169 StreamString response; 1170 1171 if (m_is_platform) 1172 { 1173 // If this packet is sent to a platform, then change the current working directory 1174 char cwd[PATH_MAX]; 1175 if (getcwd(cwd, sizeof(cwd)) == NULL) 1176 { 1177 return SendErrorResponse(errno); 1178 } 1179 else 1180 { 1181 response.PutBytesAsRawHex8(cwd, strlen(cwd)); 1182 return SendPacketNoLock(response.GetData(), response.GetSize()); 1183 } 1184 } 1185 else 1186 { 1187 const char *working_dir = m_process_launch_info.GetWorkingDirectory(); 1188 if (working_dir && working_dir[0]) 1189 { 1190 response.PutBytesAsRawHex8(working_dir, strlen(working_dir)); 1191 return SendPacketNoLock(response.GetData(), response.GetSize()); 1192 } 1193 else 1194 { 1195 return SendErrorResponse(14); 1196 } 1197 } 1198 } 1199 1200 GDBRemoteCommunication::PacketResult 1201 GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet) 1202 { 1203 packet.SetFilePos(::strlen ("QSetSTDIN:")); 1204 ProcessLaunchInfo::FileAction file_action; 1205 std::string path; 1206 packet.GetHexByteString(path); 1207 const bool read = false; 1208 const bool write = true; 1209 if (file_action.Open(STDIN_FILENO, path.c_str(), read, write)) 1210 { 1211 m_process_launch_info.AppendFileAction(file_action); 1212 return SendOKResponse (); 1213 } 1214 return SendErrorResponse (15); 1215 } 1216 1217 GDBRemoteCommunication::PacketResult 1218 GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet) 1219 { 1220 packet.SetFilePos(::strlen ("QSetSTDOUT:")); 1221 ProcessLaunchInfo::FileAction file_action; 1222 std::string path; 1223 packet.GetHexByteString(path); 1224 const bool read = true; 1225 const bool write = false; 1226 if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write)) 1227 { 1228 m_process_launch_info.AppendFileAction(file_action); 1229 return SendOKResponse (); 1230 } 1231 return SendErrorResponse (16); 1232 } 1233 1234 GDBRemoteCommunication::PacketResult 1235 GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet) 1236 { 1237 packet.SetFilePos(::strlen ("QSetSTDERR:")); 1238 ProcessLaunchInfo::FileAction file_action; 1239 std::string path; 1240 packet.GetHexByteString(path); 1241 const bool read = true; 1242 const bool write = false; 1243 if (file_action.Open(STDERR_FILENO, path.c_str(), read, write)) 1244 { 1245 m_process_launch_info.AppendFileAction(file_action); 1246 return SendOKResponse (); 1247 } 1248 return SendErrorResponse (17); 1249 } 1250 1251 GDBRemoteCommunication::PacketResult 1252 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet) 1253 { 1254 // Send response first before changing m_send_acks to we ack this packet 1255 PacketResult packet_result = SendOKResponse (); 1256 m_send_acks = false; 1257 return packet_result; 1258 } 1259 1260 GDBRemoteCommunication::PacketResult 1261 GDBRemoteCommunicationServer::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet) 1262 { 1263 packet.SetFilePos(::strlen("qPlatform_mkdir:")); 1264 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1265 if (packet.GetChar() == ',') 1266 { 1267 std::string path; 1268 packet.GetHexByteString(path); 1269 Error error = Host::MakeDirectory(path.c_str(),mode); 1270 if (error.Success()) 1271 return SendPacketNoLock ("OK", 2); 1272 else 1273 return SendErrorResponse(error.GetError()); 1274 } 1275 return SendErrorResponse(20); 1276 } 1277 1278 GDBRemoteCommunication::PacketResult 1279 GDBRemoteCommunicationServer::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet) 1280 { 1281 packet.SetFilePos(::strlen("qPlatform_chmod:")); 1282 1283 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1284 if (packet.GetChar() == ',') 1285 { 1286 std::string path; 1287 packet.GetHexByteString(path); 1288 Error error = Host::SetFilePermissions (path.c_str(), mode); 1289 if (error.Success()) 1290 return SendPacketNoLock ("OK", 2); 1291 else 1292 return SendErrorResponse(error.GetError()); 1293 } 1294 return SendErrorResponse(19); 1295 } 1296 1297 GDBRemoteCommunication::PacketResult 1298 GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet) 1299 { 1300 packet.SetFilePos(::strlen("vFile:open:")); 1301 std::string path; 1302 packet.GetHexByteStringTerminatedBy(path,','); 1303 if (!path.empty()) 1304 { 1305 if (packet.GetChar() == ',') 1306 { 1307 uint32_t flags = packet.GetHexMaxU32(false, 0); 1308 if (packet.GetChar() == ',') 1309 { 1310 mode_t mode = packet.GetHexMaxU32(false, 0600); 1311 Error error; 1312 int fd = ::open (path.c_str(), flags, mode); 1313 const int save_errno = fd == -1 ? errno : 0; 1314 StreamString response; 1315 response.PutChar('F'); 1316 response.Printf("%i", fd); 1317 if (save_errno) 1318 response.Printf(",%i", save_errno); 1319 return SendPacketNoLock(response.GetData(), response.GetSize()); 1320 } 1321 } 1322 } 1323 return SendErrorResponse(18); 1324 } 1325 1326 GDBRemoteCommunication::PacketResult 1327 GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet) 1328 { 1329 packet.SetFilePos(::strlen("vFile:close:")); 1330 int fd = packet.GetS32(-1); 1331 Error error; 1332 int err = -1; 1333 int save_errno = 0; 1334 if (fd >= 0) 1335 { 1336 err = close(fd); 1337 save_errno = err == -1 ? errno : 0; 1338 } 1339 else 1340 { 1341 save_errno = EINVAL; 1342 } 1343 StreamString response; 1344 response.PutChar('F'); 1345 response.Printf("%i", err); 1346 if (save_errno) 1347 response.Printf(",%i", save_errno); 1348 return SendPacketNoLock(response.GetData(), response.GetSize()); 1349 } 1350 1351 GDBRemoteCommunication::PacketResult 1352 GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet) 1353 { 1354 #ifdef _WIN32 1355 // Not implemented on Windows 1356 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pRead() unimplemented"); 1357 #else 1358 StreamGDBRemote response; 1359 packet.SetFilePos(::strlen("vFile:pread:")); 1360 int fd = packet.GetS32(-1); 1361 if (packet.GetChar() == ',') 1362 { 1363 uint64_t count = packet.GetU64(UINT64_MAX); 1364 if (packet.GetChar() == ',') 1365 { 1366 uint64_t offset = packet.GetU64(UINT32_MAX); 1367 if (count == UINT64_MAX) 1368 { 1369 response.Printf("F-1:%i", EINVAL); 1370 return SendPacketNoLock(response.GetData(), response.GetSize()); 1371 } 1372 1373 std::string buffer(count, 0); 1374 const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset); 1375 const int save_errno = bytes_read == -1 ? errno : 0; 1376 response.PutChar('F'); 1377 response.Printf("%zi", bytes_read); 1378 if (save_errno) 1379 response.Printf(",%i", save_errno); 1380 else 1381 { 1382 response.PutChar(';'); 1383 response.PutEscapedBytes(&buffer[0], bytes_read); 1384 } 1385 return SendPacketNoLock(response.GetData(), response.GetSize()); 1386 } 1387 } 1388 return SendErrorResponse(21); 1389 1390 #endif 1391 } 1392 1393 GDBRemoteCommunication::PacketResult 1394 GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet) 1395 { 1396 #ifdef _WIN32 1397 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pWrite() unimplemented"); 1398 #else 1399 packet.SetFilePos(::strlen("vFile:pwrite:")); 1400 1401 StreamGDBRemote response; 1402 response.PutChar('F'); 1403 1404 int fd = packet.GetU32(UINT32_MAX); 1405 if (packet.GetChar() == ',') 1406 { 1407 off_t offset = packet.GetU64(UINT32_MAX); 1408 if (packet.GetChar() == ',') 1409 { 1410 std::string buffer; 1411 if (packet.GetEscapedBinaryData(buffer)) 1412 { 1413 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset); 1414 const int save_errno = bytes_written == -1 ? errno : 0; 1415 response.Printf("%zi", bytes_written); 1416 if (save_errno) 1417 response.Printf(",%i", save_errno); 1418 } 1419 else 1420 { 1421 response.Printf ("-1,%i", EINVAL); 1422 } 1423 return SendPacketNoLock(response.GetData(), response.GetSize()); 1424 } 1425 } 1426 return SendErrorResponse(27); 1427 #endif 1428 } 1429 1430 GDBRemoteCommunication::PacketResult 1431 GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packet) 1432 { 1433 packet.SetFilePos(::strlen("vFile:size:")); 1434 std::string path; 1435 packet.GetHexByteString(path); 1436 if (!path.empty()) 1437 { 1438 lldb::user_id_t retcode = Host::GetFileSize(FileSpec(path.c_str(), false)); 1439 StreamString response; 1440 response.PutChar('F'); 1441 response.PutHex64(retcode); 1442 if (retcode == UINT64_MAX) 1443 { 1444 response.PutChar(','); 1445 response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode() 1446 } 1447 return SendPacketNoLock(response.GetData(), response.GetSize()); 1448 } 1449 return SendErrorResponse(22); 1450 } 1451 1452 GDBRemoteCommunication::PacketResult 1453 GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packet) 1454 { 1455 packet.SetFilePos(::strlen("vFile:mode:")); 1456 std::string path; 1457 packet.GetHexByteString(path); 1458 if (!path.empty()) 1459 { 1460 Error error; 1461 const uint32_t mode = File::GetPermissions(path.c_str(), error); 1462 StreamString response; 1463 response.Printf("F%u", mode); 1464 if (mode == 0 || error.Fail()) 1465 response.Printf(",%i", (int)error.GetError()); 1466 return SendPacketNoLock(response.GetData(), response.GetSize()); 1467 } 1468 return SendErrorResponse(23); 1469 } 1470 1471 GDBRemoteCommunication::PacketResult 1472 GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &packet) 1473 { 1474 packet.SetFilePos(::strlen("vFile:exists:")); 1475 std::string path; 1476 packet.GetHexByteString(path); 1477 if (!path.empty()) 1478 { 1479 bool retcode = Host::GetFileExists(FileSpec(path.c_str(), false)); 1480 StreamString response; 1481 response.PutChar('F'); 1482 response.PutChar(','); 1483 if (retcode) 1484 response.PutChar('1'); 1485 else 1486 response.PutChar('0'); 1487 return SendPacketNoLock(response.GetData(), response.GetSize()); 1488 } 1489 return SendErrorResponse(24); 1490 } 1491 1492 GDBRemoteCommunication::PacketResult 1493 GDBRemoteCommunicationServer::Handle_vFile_symlink (StringExtractorGDBRemote &packet) 1494 { 1495 packet.SetFilePos(::strlen("vFile:symlink:")); 1496 std::string dst, src; 1497 packet.GetHexByteStringTerminatedBy(dst, ','); 1498 packet.GetChar(); // Skip ',' char 1499 packet.GetHexByteString(src); 1500 Error error = Host::Symlink(src.c_str(), dst.c_str()); 1501 StreamString response; 1502 response.Printf("F%u,%u", error.GetError(), error.GetError()); 1503 return SendPacketNoLock(response.GetData(), response.GetSize()); 1504 } 1505 1506 GDBRemoteCommunication::PacketResult 1507 GDBRemoteCommunicationServer::Handle_vFile_unlink (StringExtractorGDBRemote &packet) 1508 { 1509 packet.SetFilePos(::strlen("vFile:unlink:")); 1510 std::string path; 1511 packet.GetHexByteString(path); 1512 Error error = Host::Unlink(path.c_str()); 1513 StreamString response; 1514 response.Printf("F%u,%u", error.GetError(), error.GetError()); 1515 return SendPacketNoLock(response.GetData(), response.GetSize()); 1516 } 1517 1518 GDBRemoteCommunication::PacketResult 1519 GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &packet) 1520 { 1521 packet.SetFilePos(::strlen("qPlatform_shell:")); 1522 std::string path; 1523 std::string working_dir; 1524 packet.GetHexByteStringTerminatedBy(path,','); 1525 if (!path.empty()) 1526 { 1527 if (packet.GetChar() == ',') 1528 { 1529 // FIXME: add timeout to qPlatform_shell packet 1530 // uint32_t timeout = packet.GetHexMaxU32(false, 32); 1531 uint32_t timeout = 10; 1532 if (packet.GetChar() == ',') 1533 packet.GetHexByteString(working_dir); 1534 int status, signo; 1535 std::string output; 1536 Error err = Host::RunShellCommand(path.c_str(), 1537 working_dir.empty() ? NULL : working_dir.c_str(), 1538 &status, &signo, &output, timeout); 1539 StreamGDBRemote response; 1540 if (err.Fail()) 1541 { 1542 response.PutCString("F,"); 1543 response.PutHex32(UINT32_MAX); 1544 } 1545 else 1546 { 1547 response.PutCString("F,"); 1548 response.PutHex32(status); 1549 response.PutChar(','); 1550 response.PutHex32(signo); 1551 response.PutChar(','); 1552 response.PutEscapedBytes(output.c_str(), output.size()); 1553 } 1554 return SendPacketNoLock(response.GetData(), response.GetSize()); 1555 } 1556 } 1557 return SendErrorResponse(24); 1558 } 1559 1560 GDBRemoteCommunication::PacketResult 1561 GDBRemoteCommunicationServer::Handle_vFile_Stat (StringExtractorGDBRemote &packet) 1562 { 1563 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_Stat() unimplemented"); 1564 } 1565 1566 GDBRemoteCommunication::PacketResult 1567 GDBRemoteCommunicationServer::Handle_vFile_MD5 (StringExtractorGDBRemote &packet) 1568 { 1569 packet.SetFilePos(::strlen("vFile:MD5:")); 1570 std::string path; 1571 packet.GetHexByteString(path); 1572 if (!path.empty()) 1573 { 1574 uint64_t a,b; 1575 StreamGDBRemote response; 1576 if (Host::CalculateMD5(FileSpec(path.c_str(),false),a,b) == false) 1577 { 1578 response.PutCString("F,"); 1579 response.PutCString("x"); 1580 } 1581 else 1582 { 1583 response.PutCString("F,"); 1584 response.PutHex64(a); 1585 response.PutHex64(b); 1586 } 1587 return SendPacketNoLock(response.GetData(), response.GetSize()); 1588 } 1589 return SendErrorResponse(25); 1590 } 1591 1592