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