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 // FIXME: remove linux restriction once eLaunchFlagDebug is supported 815 #if !defined (__linux__) 816 m_process_launch_info.GetFlags().Set (eLaunchFlagDebug); 817 #endif 818 m_process_launch_error = LaunchProcess (); 819 if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 820 { 821 return SendOKResponse (); 822 } 823 } 824 return SendErrorResponse (8); 825 } 826 827 GDBRemoteCommunication::PacketResult 828 GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet) 829 { 830 lldb::pid_t pid = m_process_launch_info.GetProcessID(); 831 StreamString response; 832 response.Printf("QC%" PRIx64, pid); 833 if (m_is_platform) 834 { 835 // If we launch a process and this GDB server is acting as a platform, 836 // then we need to clear the process launch state so we can start 837 // launching another process. In order to launch a process a bunch or 838 // packets need to be sent: environment packets, working directory, 839 // disable ASLR, and many more settings. When we launch a process we 840 // then need to know when to clear this information. Currently we are 841 // selecting the 'qC' packet as that packet which seems to make the most 842 // sense. 843 if (pid != LLDB_INVALID_PROCESS_ID) 844 { 845 m_process_launch_info.Clear(); 846 } 847 } 848 return SendPacketNoLock (response.GetData(), response.GetSize()); 849 } 850 851 bool 852 GDBRemoteCommunicationServer::DebugserverProcessReaped (lldb::pid_t pid) 853 { 854 Mutex::Locker locker (m_spawned_pids_mutex); 855 FreePortForProcess(pid); 856 return m_spawned_pids.erase(pid) > 0; 857 } 858 bool 859 GDBRemoteCommunicationServer::ReapDebugserverProcess (void *callback_baton, 860 lldb::pid_t pid, 861 bool exited, 862 int signal, // Zero for no signal 863 int status) // Exit value of process if signal is zero 864 { 865 GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton; 866 server->DebugserverProcessReaped (pid); 867 return true; 868 } 869 870 bool 871 GDBRemoteCommunicationServer::DebuggedProcessReaped (lldb::pid_t pid) 872 { 873 // reap a process that we were debugging (but not debugserver) 874 Mutex::Locker locker (m_spawned_pids_mutex); 875 return m_spawned_pids.erase(pid) > 0; 876 } 877 878 bool 879 GDBRemoteCommunicationServer::ReapDebuggedProcess (void *callback_baton, 880 lldb::pid_t pid, 881 bool exited, 882 int signal, // Zero for no signal 883 int status) // Exit value of process if signal is zero 884 { 885 GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton; 886 server->DebuggedProcessReaped (pid); 887 return true; 888 } 889 890 GDBRemoteCommunication::PacketResult 891 GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet) 892 { 893 #ifdef _WIN32 894 return SendErrorResponse(9); 895 #else 896 // Spawn a local debugserver as a platform so we can then attach or launch 897 // a process... 898 899 if (m_is_platform) 900 { 901 // Sleep and wait a bit for debugserver to start to listen... 902 ConnectionFileDescriptor file_conn; 903 Error error; 904 std::string hostname; 905 // TODO: /tmp/ should not be hardcoded. User might want to override /tmp 906 // with the TMPDIR environnement variable 907 packet.SetFilePos(::strlen ("qLaunchGDBServer;")); 908 std::string name; 909 std::string value; 910 uint16_t port = UINT16_MAX; 911 while (packet.GetNameColonValue(name, value)) 912 { 913 if (name.compare ("host") == 0) 914 hostname.swap(value); 915 else if (name.compare ("port") == 0) 916 port = Args::StringToUInt32(value.c_str(), 0, 0); 917 } 918 if (port == UINT16_MAX) 919 port = GetNextAvailablePort(); 920 921 // Spawn a new thread to accept the port that gets bound after 922 // binding to port 0 (zero). 923 924 if (error.Success()) 925 { 926 // Spawn a debugserver and try to get the port it listens to. 927 ProcessLaunchInfo debugserver_launch_info; 928 if (hostname.empty()) 929 hostname = "localhost"; 930 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 931 if (log) 932 log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port); 933 934 debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); 935 936 error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(), 937 port, 938 debugserver_launch_info, 939 port); 940 941 lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); 942 943 944 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 945 { 946 Mutex::Locker locker (m_spawned_pids_mutex); 947 m_spawned_pids.insert(debugserver_pid); 948 if (port > 0) 949 AssociatePortWithProcess(port, debugserver_pid); 950 } 951 else 952 { 953 if (port > 0) 954 FreePort (port); 955 } 956 957 if (error.Success()) 958 { 959 char response[256]; 960 const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset); 961 assert (response_len < sizeof(response)); 962 PacketResult packet_result = SendPacketNoLock (response, response_len); 963 964 if (packet_result != PacketResult::Success) 965 { 966 if (debugserver_pid != LLDB_INVALID_PROCESS_ID) 967 ::kill (debugserver_pid, SIGINT); 968 } 969 return packet_result; 970 } 971 } 972 } 973 return SendErrorResponse (9); 974 #endif 975 } 976 977 bool 978 GDBRemoteCommunicationServer::KillSpawnedProcess (lldb::pid_t pid) 979 { 980 // make sure we know about this process 981 { 982 Mutex::Locker locker (m_spawned_pids_mutex); 983 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 984 return false; 985 } 986 987 // first try a SIGTERM (standard kill) 988 Host::Kill (pid, SIGTERM); 989 990 // check if that worked 991 for (size_t i=0; i<10; ++i) 992 { 993 { 994 Mutex::Locker locker (m_spawned_pids_mutex); 995 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 996 { 997 // it is now killed 998 return true; 999 } 1000 } 1001 usleep (10000); 1002 } 1003 1004 // check one more time after the final usleep 1005 { 1006 Mutex::Locker locker (m_spawned_pids_mutex); 1007 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1008 return true; 1009 } 1010 1011 // the launched process still lives. Now try killling it again, 1012 // this time with an unblockable signal. 1013 Host::Kill (pid, SIGKILL); 1014 1015 for (size_t i=0; i<10; ++i) 1016 { 1017 { 1018 Mutex::Locker locker (m_spawned_pids_mutex); 1019 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1020 { 1021 // it is now killed 1022 return true; 1023 } 1024 } 1025 usleep (10000); 1026 } 1027 1028 // check one more time after the final usleep 1029 // Scope for locker 1030 { 1031 Mutex::Locker locker (m_spawned_pids_mutex); 1032 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1033 return true; 1034 } 1035 1036 // no luck - the process still lives 1037 return false; 1038 } 1039 1040 GDBRemoteCommunication::PacketResult 1041 GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet) 1042 { 1043 packet.SetFilePos(::strlen ("qKillSpawnedProcess:")); 1044 1045 lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID); 1046 1047 // verify that we know anything about this pid. 1048 // Scope for locker 1049 { 1050 Mutex::Locker locker (m_spawned_pids_mutex); 1051 if (m_spawned_pids.find(pid) == m_spawned_pids.end()) 1052 { 1053 // not a pid we know about 1054 return SendErrorResponse (10); 1055 } 1056 } 1057 1058 // go ahead and attempt to kill the spawned process 1059 if (KillSpawnedProcess (pid)) 1060 return SendOKResponse (); 1061 else 1062 return SendErrorResponse (11); 1063 } 1064 1065 GDBRemoteCommunication::PacketResult 1066 GDBRemoteCommunicationServer::Handle_k (StringExtractorGDBRemote &packet) 1067 { 1068 // ignore for now if we're lldb_platform 1069 if (m_is_platform) 1070 return SendUnimplementedResponse (packet.GetStringRef().c_str()); 1071 1072 // shutdown all spawned processes 1073 std::set<lldb::pid_t> spawned_pids_copy; 1074 1075 // copy pids 1076 { 1077 Mutex::Locker locker (m_spawned_pids_mutex); 1078 spawned_pids_copy.insert (m_spawned_pids.begin (), m_spawned_pids.end ()); 1079 } 1080 1081 // nuke the spawned processes 1082 for (auto it = spawned_pids_copy.begin (); it != spawned_pids_copy.end (); ++it) 1083 { 1084 lldb::pid_t spawned_pid = *it; 1085 if (!KillSpawnedProcess (spawned_pid)) 1086 { 1087 fprintf (stderr, "%s: failed to kill spawned pid %" PRIu64 ", ignoring.\n", __FUNCTION__, spawned_pid); 1088 } 1089 } 1090 1091 // TODO figure out how to shut down gracefully at this point 1092 return SendOKResponse (); 1093 } 1094 1095 GDBRemoteCommunication::PacketResult 1096 GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet) 1097 { 1098 if (m_process_launch_error.Success()) 1099 return SendOKResponse(); 1100 StreamString response; 1101 response.PutChar('E'); 1102 response.PutCString(m_process_launch_error.AsCString("<unknown error>")); 1103 return SendPacketNoLock (response.GetData(), response.GetSize()); 1104 } 1105 1106 GDBRemoteCommunication::PacketResult 1107 GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &packet) 1108 { 1109 packet.SetFilePos(::strlen ("QEnvironment:")); 1110 const uint32_t bytes_left = packet.GetBytesLeft(); 1111 if (bytes_left > 0) 1112 { 1113 m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek()); 1114 return SendOKResponse (); 1115 } 1116 return SendErrorResponse (12); 1117 } 1118 1119 GDBRemoteCommunication::PacketResult 1120 GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &packet) 1121 { 1122 packet.SetFilePos(::strlen ("QLaunchArch:")); 1123 const uint32_t bytes_left = packet.GetBytesLeft(); 1124 if (bytes_left > 0) 1125 { 1126 const char* arch_triple = packet.Peek(); 1127 ArchSpec arch_spec(arch_triple,NULL); 1128 m_process_launch_info.SetArchitecture(arch_spec); 1129 return SendOKResponse(); 1130 } 1131 return SendErrorResponse(13); 1132 } 1133 1134 GDBRemoteCommunication::PacketResult 1135 GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet) 1136 { 1137 packet.SetFilePos(::strlen ("QSetDisableASLR:")); 1138 if (packet.GetU32(0)) 1139 m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR); 1140 else 1141 m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); 1142 return SendOKResponse (); 1143 } 1144 1145 GDBRemoteCommunication::PacketResult 1146 GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet) 1147 { 1148 packet.SetFilePos(::strlen ("QSetWorkingDir:")); 1149 std::string path; 1150 packet.GetHexByteString(path); 1151 if (m_is_platform) 1152 { 1153 #ifdef _WIN32 1154 // Not implemented on Windows 1155 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_QSetWorkingDir unimplemented"); 1156 #else 1157 // If this packet is sent to a platform, then change the current working directory 1158 if (::chdir(path.c_str()) != 0) 1159 return SendErrorResponse(errno); 1160 #endif 1161 } 1162 else 1163 { 1164 m_process_launch_info.SwapWorkingDirectory (path); 1165 } 1166 return SendOKResponse (); 1167 } 1168 1169 GDBRemoteCommunication::PacketResult 1170 GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet) 1171 { 1172 StreamString response; 1173 1174 if (m_is_platform) 1175 { 1176 // If this packet is sent to a platform, then change the current working directory 1177 char cwd[PATH_MAX]; 1178 if (getcwd(cwd, sizeof(cwd)) == NULL) 1179 { 1180 return SendErrorResponse(errno); 1181 } 1182 else 1183 { 1184 response.PutBytesAsRawHex8(cwd, strlen(cwd)); 1185 return SendPacketNoLock(response.GetData(), response.GetSize()); 1186 } 1187 } 1188 else 1189 { 1190 const char *working_dir = m_process_launch_info.GetWorkingDirectory(); 1191 if (working_dir && working_dir[0]) 1192 { 1193 response.PutBytesAsRawHex8(working_dir, strlen(working_dir)); 1194 return SendPacketNoLock(response.GetData(), response.GetSize()); 1195 } 1196 else 1197 { 1198 return SendErrorResponse(14); 1199 } 1200 } 1201 } 1202 1203 GDBRemoteCommunication::PacketResult 1204 GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet) 1205 { 1206 packet.SetFilePos(::strlen ("QSetSTDIN:")); 1207 ProcessLaunchInfo::FileAction file_action; 1208 std::string path; 1209 packet.GetHexByteString(path); 1210 const bool read = false; 1211 const bool write = true; 1212 if (file_action.Open(STDIN_FILENO, path.c_str(), read, write)) 1213 { 1214 m_process_launch_info.AppendFileAction(file_action); 1215 return SendOKResponse (); 1216 } 1217 return SendErrorResponse (15); 1218 } 1219 1220 GDBRemoteCommunication::PacketResult 1221 GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet) 1222 { 1223 packet.SetFilePos(::strlen ("QSetSTDOUT:")); 1224 ProcessLaunchInfo::FileAction file_action; 1225 std::string path; 1226 packet.GetHexByteString(path); 1227 const bool read = true; 1228 const bool write = false; 1229 if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write)) 1230 { 1231 m_process_launch_info.AppendFileAction(file_action); 1232 return SendOKResponse (); 1233 } 1234 return SendErrorResponse (16); 1235 } 1236 1237 GDBRemoteCommunication::PacketResult 1238 GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet) 1239 { 1240 packet.SetFilePos(::strlen ("QSetSTDERR:")); 1241 ProcessLaunchInfo::FileAction file_action; 1242 std::string path; 1243 packet.GetHexByteString(path); 1244 const bool read = true; 1245 const bool write = false; 1246 if (file_action.Open(STDERR_FILENO, path.c_str(), read, write)) 1247 { 1248 m_process_launch_info.AppendFileAction(file_action); 1249 return SendOKResponse (); 1250 } 1251 return SendErrorResponse (17); 1252 } 1253 1254 GDBRemoteCommunication::PacketResult 1255 GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet) 1256 { 1257 // Send response first before changing m_send_acks to we ack this packet 1258 PacketResult packet_result = SendOKResponse (); 1259 m_send_acks = false; 1260 return packet_result; 1261 } 1262 1263 GDBRemoteCommunication::PacketResult 1264 GDBRemoteCommunicationServer::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet) 1265 { 1266 packet.SetFilePos(::strlen("qPlatform_mkdir:")); 1267 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1268 if (packet.GetChar() == ',') 1269 { 1270 std::string path; 1271 packet.GetHexByteString(path); 1272 Error error = Host::MakeDirectory(path.c_str(),mode); 1273 if (error.Success()) 1274 return SendPacketNoLock ("OK", 2); 1275 else 1276 return SendErrorResponse(error.GetError()); 1277 } 1278 return SendErrorResponse(20); 1279 } 1280 1281 GDBRemoteCommunication::PacketResult 1282 GDBRemoteCommunicationServer::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet) 1283 { 1284 packet.SetFilePos(::strlen("qPlatform_chmod:")); 1285 1286 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 1287 if (packet.GetChar() == ',') 1288 { 1289 std::string path; 1290 packet.GetHexByteString(path); 1291 Error error = Host::SetFilePermissions (path.c_str(), mode); 1292 if (error.Success()) 1293 return SendPacketNoLock ("OK", 2); 1294 else 1295 return SendErrorResponse(error.GetError()); 1296 } 1297 return SendErrorResponse(19); 1298 } 1299 1300 GDBRemoteCommunication::PacketResult 1301 GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet) 1302 { 1303 packet.SetFilePos(::strlen("vFile:open:")); 1304 std::string path; 1305 packet.GetHexByteStringTerminatedBy(path,','); 1306 if (!path.empty()) 1307 { 1308 if (packet.GetChar() == ',') 1309 { 1310 uint32_t flags = packet.GetHexMaxU32(false, 0); 1311 if (packet.GetChar() == ',') 1312 { 1313 mode_t mode = packet.GetHexMaxU32(false, 0600); 1314 Error error; 1315 int fd = ::open (path.c_str(), flags, mode); 1316 const int save_errno = fd == -1 ? errno : 0; 1317 StreamString response; 1318 response.PutChar('F'); 1319 response.Printf("%i", fd); 1320 if (save_errno) 1321 response.Printf(",%i", save_errno); 1322 return SendPacketNoLock(response.GetData(), response.GetSize()); 1323 } 1324 } 1325 } 1326 return SendErrorResponse(18); 1327 } 1328 1329 GDBRemoteCommunication::PacketResult 1330 GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet) 1331 { 1332 packet.SetFilePos(::strlen("vFile:close:")); 1333 int fd = packet.GetS32(-1); 1334 Error error; 1335 int err = -1; 1336 int save_errno = 0; 1337 if (fd >= 0) 1338 { 1339 err = close(fd); 1340 save_errno = err == -1 ? errno : 0; 1341 } 1342 else 1343 { 1344 save_errno = EINVAL; 1345 } 1346 StreamString response; 1347 response.PutChar('F'); 1348 response.Printf("%i", err); 1349 if (save_errno) 1350 response.Printf(",%i", save_errno); 1351 return SendPacketNoLock(response.GetData(), response.GetSize()); 1352 } 1353 1354 GDBRemoteCommunication::PacketResult 1355 GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet) 1356 { 1357 #ifdef _WIN32 1358 // Not implemented on Windows 1359 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pRead() unimplemented"); 1360 #else 1361 StreamGDBRemote response; 1362 packet.SetFilePos(::strlen("vFile:pread:")); 1363 int fd = packet.GetS32(-1); 1364 if (packet.GetChar() == ',') 1365 { 1366 uint64_t count = packet.GetU64(UINT64_MAX); 1367 if (packet.GetChar() == ',') 1368 { 1369 uint64_t offset = packet.GetU64(UINT32_MAX); 1370 if (count == UINT64_MAX) 1371 { 1372 response.Printf("F-1:%i", EINVAL); 1373 return SendPacketNoLock(response.GetData(), response.GetSize()); 1374 } 1375 1376 std::string buffer(count, 0); 1377 const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset); 1378 const int save_errno = bytes_read == -1 ? errno : 0; 1379 response.PutChar('F'); 1380 response.Printf("%zi", bytes_read); 1381 if (save_errno) 1382 response.Printf(",%i", save_errno); 1383 else 1384 { 1385 response.PutChar(';'); 1386 response.PutEscapedBytes(&buffer[0], bytes_read); 1387 } 1388 return SendPacketNoLock(response.GetData(), response.GetSize()); 1389 } 1390 } 1391 return SendErrorResponse(21); 1392 1393 #endif 1394 } 1395 1396 GDBRemoteCommunication::PacketResult 1397 GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet) 1398 { 1399 #ifdef _WIN32 1400 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pWrite() unimplemented"); 1401 #else 1402 packet.SetFilePos(::strlen("vFile:pwrite:")); 1403 1404 StreamGDBRemote response; 1405 response.PutChar('F'); 1406 1407 int fd = packet.GetU32(UINT32_MAX); 1408 if (packet.GetChar() == ',') 1409 { 1410 off_t offset = packet.GetU64(UINT32_MAX); 1411 if (packet.GetChar() == ',') 1412 { 1413 std::string buffer; 1414 if (packet.GetEscapedBinaryData(buffer)) 1415 { 1416 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset); 1417 const int save_errno = bytes_written == -1 ? errno : 0; 1418 response.Printf("%zi", bytes_written); 1419 if (save_errno) 1420 response.Printf(",%i", save_errno); 1421 } 1422 else 1423 { 1424 response.Printf ("-1,%i", EINVAL); 1425 } 1426 return SendPacketNoLock(response.GetData(), response.GetSize()); 1427 } 1428 } 1429 return SendErrorResponse(27); 1430 #endif 1431 } 1432 1433 GDBRemoteCommunication::PacketResult 1434 GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packet) 1435 { 1436 packet.SetFilePos(::strlen("vFile:size:")); 1437 std::string path; 1438 packet.GetHexByteString(path); 1439 if (!path.empty()) 1440 { 1441 lldb::user_id_t retcode = Host::GetFileSize(FileSpec(path.c_str(), false)); 1442 StreamString response; 1443 response.PutChar('F'); 1444 response.PutHex64(retcode); 1445 if (retcode == UINT64_MAX) 1446 { 1447 response.PutChar(','); 1448 response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode() 1449 } 1450 return SendPacketNoLock(response.GetData(), response.GetSize()); 1451 } 1452 return SendErrorResponse(22); 1453 } 1454 1455 GDBRemoteCommunication::PacketResult 1456 GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packet) 1457 { 1458 packet.SetFilePos(::strlen("vFile:mode:")); 1459 std::string path; 1460 packet.GetHexByteString(path); 1461 if (!path.empty()) 1462 { 1463 Error error; 1464 const uint32_t mode = File::GetPermissions(path.c_str(), error); 1465 StreamString response; 1466 response.Printf("F%u", mode); 1467 if (mode == 0 || error.Fail()) 1468 response.Printf(",%i", (int)error.GetError()); 1469 return SendPacketNoLock(response.GetData(), response.GetSize()); 1470 } 1471 return SendErrorResponse(23); 1472 } 1473 1474 GDBRemoteCommunication::PacketResult 1475 GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &packet) 1476 { 1477 packet.SetFilePos(::strlen("vFile:exists:")); 1478 std::string path; 1479 packet.GetHexByteString(path); 1480 if (!path.empty()) 1481 { 1482 bool retcode = Host::GetFileExists(FileSpec(path.c_str(), false)); 1483 StreamString response; 1484 response.PutChar('F'); 1485 response.PutChar(','); 1486 if (retcode) 1487 response.PutChar('1'); 1488 else 1489 response.PutChar('0'); 1490 return SendPacketNoLock(response.GetData(), response.GetSize()); 1491 } 1492 return SendErrorResponse(24); 1493 } 1494 1495 GDBRemoteCommunication::PacketResult 1496 GDBRemoteCommunicationServer::Handle_vFile_symlink (StringExtractorGDBRemote &packet) 1497 { 1498 packet.SetFilePos(::strlen("vFile:symlink:")); 1499 std::string dst, src; 1500 packet.GetHexByteStringTerminatedBy(dst, ','); 1501 packet.GetChar(); // Skip ',' char 1502 packet.GetHexByteString(src); 1503 Error error = Host::Symlink(src.c_str(), dst.c_str()); 1504 StreamString response; 1505 response.Printf("F%u,%u", error.GetError(), error.GetError()); 1506 return SendPacketNoLock(response.GetData(), response.GetSize()); 1507 } 1508 1509 GDBRemoteCommunication::PacketResult 1510 GDBRemoteCommunicationServer::Handle_vFile_unlink (StringExtractorGDBRemote &packet) 1511 { 1512 packet.SetFilePos(::strlen("vFile:unlink:")); 1513 std::string path; 1514 packet.GetHexByteString(path); 1515 Error error = Host::Unlink(path.c_str()); 1516 StreamString response; 1517 response.Printf("F%u,%u", error.GetError(), error.GetError()); 1518 return SendPacketNoLock(response.GetData(), response.GetSize()); 1519 } 1520 1521 GDBRemoteCommunication::PacketResult 1522 GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &packet) 1523 { 1524 packet.SetFilePos(::strlen("qPlatform_shell:")); 1525 std::string path; 1526 std::string working_dir; 1527 packet.GetHexByteStringTerminatedBy(path,','); 1528 if (!path.empty()) 1529 { 1530 if (packet.GetChar() == ',') 1531 { 1532 // FIXME: add timeout to qPlatform_shell packet 1533 // uint32_t timeout = packet.GetHexMaxU32(false, 32); 1534 uint32_t timeout = 10; 1535 if (packet.GetChar() == ',') 1536 packet.GetHexByteString(working_dir); 1537 int status, signo; 1538 std::string output; 1539 Error err = Host::RunShellCommand(path.c_str(), 1540 working_dir.empty() ? NULL : working_dir.c_str(), 1541 &status, &signo, &output, timeout); 1542 StreamGDBRemote response; 1543 if (err.Fail()) 1544 { 1545 response.PutCString("F,"); 1546 response.PutHex32(UINT32_MAX); 1547 } 1548 else 1549 { 1550 response.PutCString("F,"); 1551 response.PutHex32(status); 1552 response.PutChar(','); 1553 response.PutHex32(signo); 1554 response.PutChar(','); 1555 response.PutEscapedBytes(output.c_str(), output.size()); 1556 } 1557 return SendPacketNoLock(response.GetData(), response.GetSize()); 1558 } 1559 } 1560 return SendErrorResponse(24); 1561 } 1562 1563 GDBRemoteCommunication::PacketResult 1564 GDBRemoteCommunicationServer::Handle_vFile_Stat (StringExtractorGDBRemote &packet) 1565 { 1566 return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_Stat() unimplemented"); 1567 } 1568 1569 GDBRemoteCommunication::PacketResult 1570 GDBRemoteCommunicationServer::Handle_vFile_MD5 (StringExtractorGDBRemote &packet) 1571 { 1572 packet.SetFilePos(::strlen("vFile:MD5:")); 1573 std::string path; 1574 packet.GetHexByteString(path); 1575 if (!path.empty()) 1576 { 1577 uint64_t a,b; 1578 StreamGDBRemote response; 1579 if (Host::CalculateMD5(FileSpec(path.c_str(),false),a,b) == false) 1580 { 1581 response.PutCString("F,"); 1582 response.PutCString("x"); 1583 } 1584 else 1585 { 1586 response.PutCString("F,"); 1587 response.PutHex64(a); 1588 response.PutHex64(b); 1589 } 1590 return SendPacketNoLock(response.GetData(), response.GetSize()); 1591 } 1592 return SendErrorResponse(25); 1593 } 1594 1595