ProcessKDP.cpp revision 952e9dc874944fcdbbb224f3ec4fc2c859376f64
1//===-- ProcessKDP.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// C Includes 11#include <errno.h> 12#include <stdlib.h> 13 14// C++ Includes 15// Other libraries and framework includes 16#include "lldb/Core/ConnectionFileDescriptor.h" 17#include "lldb/Core/Debugger.h" 18#include "lldb/Core/PluginManager.h" 19#include "lldb/Core/Module.h" 20#include "lldb/Core/ModuleSpec.h" 21#include "lldb/Core/State.h" 22#include "lldb/Core/UUID.h" 23#include "lldb/Host/Host.h" 24#include "lldb/Host/Symbols.h" 25#include "lldb/Interpreter/CommandInterpreter.h" 26#include "lldb/Interpreter/CommandObject.h" 27#include "lldb/Interpreter/CommandObjectMultiword.h" 28#include "lldb/Interpreter/CommandReturnObject.h" 29#include "lldb/Interpreter/OptionGroupString.h" 30#include "lldb/Interpreter/OptionGroupUInt64.h" 31#include "lldb/Symbol/ObjectFile.h" 32#include "lldb/Target/RegisterContext.h" 33#include "lldb/Target/Target.h" 34#include "lldb/Target/Thread.h" 35 36// Project includes 37#include "ProcessKDP.h" 38#include "ProcessKDPLog.h" 39#include "ThreadKDP.h" 40#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" 41#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" 42#include "Utility/StringExtractor.h" 43 44using namespace lldb; 45using namespace lldb_private; 46 47const char * 48ProcessKDP::GetPluginNameStatic() 49{ 50 return "kdp-remote"; 51} 52 53const char * 54ProcessKDP::GetPluginDescriptionStatic() 55{ 56 return "KDP Remote protocol based debugging plug-in for darwin kernel debugging."; 57} 58 59void 60ProcessKDP::Terminate() 61{ 62 PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance); 63} 64 65 66lldb::ProcessSP 67ProcessKDP::CreateInstance (Target &target, 68 Listener &listener, 69 const FileSpec *crash_file_path) 70{ 71 lldb::ProcessSP process_sp; 72 if (crash_file_path == NULL) 73 process_sp.reset(new ProcessKDP (target, listener)); 74 return process_sp; 75} 76 77bool 78ProcessKDP::CanDebug(Target &target, bool plugin_specified_by_name) 79{ 80 if (plugin_specified_by_name) 81 return true; 82 83 // For now we are just making sure the file exists for a given module 84 Module *exe_module = target.GetExecutableModulePointer(); 85 if (exe_module) 86 { 87 const llvm::Triple &triple_ref = target.GetArchitecture().GetTriple(); 88 switch (triple_ref.getOS()) 89 { 90 case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for iOS, but accept darwin just in case 91 case llvm::Triple::MacOSX: // For desktop targets 92 case llvm::Triple::IOS: // For arm targets 93 if (triple_ref.getVendor() == llvm::Triple::Apple) 94 { 95 ObjectFile *exe_objfile = exe_module->GetObjectFile(); 96 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && 97 exe_objfile->GetStrata() == ObjectFile::eStrataKernel) 98 return true; 99 } 100 break; 101 102 default: 103 break; 104 } 105 } 106 return false; 107} 108 109//---------------------------------------------------------------------- 110// ProcessKDP constructor 111//---------------------------------------------------------------------- 112ProcessKDP::ProcessKDP(Target& target, Listener &listener) : 113 Process (target, listener), 114 m_comm("lldb.process.kdp-remote.communication"), 115 m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"), 116 m_async_thread (LLDB_INVALID_HOST_THREAD), 117 m_dyld_plugin_name (), 118 m_kernel_load_addr (LLDB_INVALID_ADDRESS), 119 m_command_sp() 120{ 121 m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); 122 m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue"); 123} 124 125//---------------------------------------------------------------------- 126// Destructor 127//---------------------------------------------------------------------- 128ProcessKDP::~ProcessKDP() 129{ 130 Clear(); 131 // We need to call finalize on the process before destroying ourselves 132 // to make sure all of the broadcaster cleanup goes as planned. If we 133 // destruct this class, then Process::~Process() might have problems 134 // trying to fully destroy the broadcaster. 135 Finalize(); 136} 137 138//---------------------------------------------------------------------- 139// PluginInterface 140//---------------------------------------------------------------------- 141const char * 142ProcessKDP::GetPluginName() 143{ 144 return "Process debugging plug-in that uses the Darwin KDP remote protocol"; 145} 146 147const char * 148ProcessKDP::GetShortPluginName() 149{ 150 return GetPluginNameStatic(); 151} 152 153uint32_t 154ProcessKDP::GetPluginVersion() 155{ 156 return 1; 157} 158 159Error 160ProcessKDP::WillLaunch (Module* module) 161{ 162 Error error; 163 error.SetErrorString ("launching not supported in kdp-remote plug-in"); 164 return error; 165} 166 167Error 168ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid) 169{ 170 Error error; 171 error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in"); 172 return error; 173} 174 175Error 176ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) 177{ 178 Error error; 179 error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in"); 180 return error; 181} 182 183Error 184ProcessKDP::DoConnectRemote (Stream *strm, const char *remote_url) 185{ 186 Error error; 187 188 // Don't let any JIT happen when doing KDP as we can't allocate 189 // memory and we don't want to be mucking with threads that might 190 // already be handling exceptions 191 SetCanJIT(false); 192 193 if (remote_url == NULL || remote_url[0] == '\0') 194 { 195 error.SetErrorStringWithFormat ("invalid connection URL '%s'", remote_url); 196 return error; 197 } 198 199 std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); 200 if (conn_ap.get()) 201 { 202 // Only try once for now. 203 // TODO: check if we should be retrying? 204 const uint32_t max_retry_count = 1; 205 for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count) 206 { 207 if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess) 208 break; 209 usleep (100000); 210 } 211 } 212 213 if (conn_ap->IsConnected()) 214 { 215 const uint16_t reply_port = conn_ap->GetReadPort (); 216 217 if (reply_port != 0) 218 { 219 m_comm.SetConnection(conn_ap.release()); 220 221 if (m_comm.SendRequestReattach(reply_port)) 222 { 223 if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB...")) 224 { 225 m_comm.GetVersion(); 226 uint32_t cpu = m_comm.GetCPUType(); 227 uint32_t sub = m_comm.GetCPUSubtype(); 228 ArchSpec kernel_arch; 229 kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub); 230 m_target.SetArchitecture(kernel_arch); 231 232 /* Get the kernel's UUID and load address via KDP_KERNELVERSION packet. */ 233 /* An EFI kdp session has neither UUID nor load address. */ 234 235 UUID kernel_uuid = m_comm.GetUUID (); 236 addr_t kernel_load_addr = m_comm.GetLoadAddress (); 237 238 if (m_comm.RemoteIsEFI ()) 239 { 240 m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic(); 241 } 242 else if (kernel_load_addr != LLDB_INVALID_ADDRESS) 243 { 244 m_kernel_load_addr = kernel_load_addr; 245 m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); 246 } 247 248 // Set the thread ID 249 UpdateThreadListIfNeeded (); 250 SetID (1); 251 GetThreadList (); 252 SetPrivateState (eStateStopped); 253 StreamSP async_strm_sp(m_target.GetDebugger().GetAsyncOutputStream()); 254 if (async_strm_sp) 255 { 256 const char *cstr; 257 if ((cstr = m_comm.GetKernelVersion ()) != NULL) 258 { 259 async_strm_sp->Printf ("Version: %s\n", cstr); 260 async_strm_sp->Flush(); 261 } 262// if ((cstr = m_comm.GetImagePath ()) != NULL) 263// { 264// async_strm_sp->Printf ("Image Path: %s\n", cstr); 265// async_strm_sp->Flush(); 266// } 267 } 268 } 269 else 270 { 271 error.SetErrorString("KDP_REATTACH failed"); 272 } 273 } 274 else 275 { 276 error.SetErrorString("KDP_REATTACH failed"); 277 } 278 } 279 else 280 { 281 error.SetErrorString("invalid reply port from UDP connection"); 282 } 283 } 284 else 285 { 286 if (error.Success()) 287 error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url); 288 } 289 if (error.Fail()) 290 m_comm.Disconnect(); 291 292 return error; 293} 294 295//---------------------------------------------------------------------- 296// Process Control 297//---------------------------------------------------------------------- 298Error 299ProcessKDP::DoLaunch (Module *exe_module, 300 const ProcessLaunchInfo &launch_info) 301{ 302 Error error; 303 error.SetErrorString ("launching not supported in kdp-remote plug-in"); 304 return error; 305} 306 307 308Error 309ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid) 310{ 311 Error error; 312 error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging"); 313 return error; 314} 315 316Error 317ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) 318{ 319 Error error; 320 error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging"); 321 return error; 322} 323 324Error 325ProcessKDP::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch, const ProcessAttachInfo &attach_info) 326{ 327 Error error; 328 error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging"); 329 return error; 330} 331 332 333void 334ProcessKDP::DidAttach () 335{ 336 Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); 337 if (log) 338 log->Printf ("ProcessKDP::DidAttach()"); 339 if (GetID() != LLDB_INVALID_PROCESS_ID) 340 { 341 // TODO: figure out the register context that we will use 342 } 343} 344 345addr_t 346ProcessKDP::GetImageInfoAddress() 347{ 348 return m_kernel_load_addr; 349} 350 351lldb_private::DynamicLoader * 352ProcessKDP::GetDynamicLoader () 353{ 354 if (m_dyld_ap.get() == NULL) 355 m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.empty() ? NULL : m_dyld_plugin_name.c_str())); 356 return m_dyld_ap.get(); 357} 358 359Error 360ProcessKDP::WillResume () 361{ 362 return Error(); 363} 364 365Error 366ProcessKDP::DoResume () 367{ 368 Error error; 369 Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); 370 // Only start the async thread if we try to do any process control 371 if (!IS_VALID_LLDB_HOST_THREAD(m_async_thread)) 372 StartAsyncThread (); 373 374 bool resume = false; 375 376 // With KDP there is only one thread we can tell what to do 377 ThreadSP kernel_thread_sp (GetKernelThread(m_thread_list, m_thread_list)); 378 if (kernel_thread_sp) 379 { 380 const StateType thread_resume_state = kernel_thread_sp->GetTemporaryResumeState(); 381 switch (thread_resume_state) 382 { 383 case eStateSuspended: 384 // Nothing to do here when a thread will stay suspended 385 // we just leave the CPU mask bit set to zero for the thread 386 break; 387 388 case eStateStepping: 389 kernel_thread_sp->GetRegisterContext()->HardwareSingleStep (true); 390 resume = true; 391 break; 392 393 case eStateRunning: 394 kernel_thread_sp->GetRegisterContext()->HardwareSingleStep (false); 395 resume = true; 396 break; 397 398 default: 399 // The only valid thread resume states are listed above 400 assert (!"invalid thread resume state"); 401 break; 402 } 403 } 404 405 if (resume) 406 { 407 if (log) 408 log->Printf ("ProcessKDP::DoResume () sending resume"); 409 410 if (m_comm.SendRequestResume ()) 411 { 412 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue); 413 SetPrivateState(eStateRunning); 414 } 415 else 416 error.SetErrorString ("KDP resume failed"); 417 } 418 else 419 { 420 error.SetErrorString ("kernel thread is suspended"); 421 } 422 423 return error; 424} 425 426lldb::ThreadSP 427ProcessKDP::GetKernelThread(ThreadList &old_thread_list, ThreadList &new_thread_list) 428{ 429 // KDP only tells us about one thread/core. Any other threads will usually 430 // be the ones that are read from memory by the OS plug-ins. 431 const lldb::tid_t kernel_tid = 1; 432 ThreadSP thread_sp (old_thread_list.FindThreadByID (kernel_tid, false)); 433 if (!thread_sp) 434 { 435 thread_sp.reset(new ThreadKDP (*this, kernel_tid)); 436 new_thread_list.AddThread(thread_sp); 437 } 438 return thread_sp; 439} 440 441 442 443 444bool 445ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) 446{ 447 // locker will keep a mutex locked until it goes out of scope 448 Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD)); 449 if (log && log->GetMask().Test(KDP_LOG_VERBOSE)) 450 log->Printf ("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID()); 451 452 // Even though there is a CPU mask, it doesn't mean to can see each CPU 453 // indivudually, there is really only one. Lets call this thread 1. 454 GetKernelThread (old_thread_list, new_thread_list); 455 456 return new_thread_list.GetSize(false) > 0; 457} 458 459void 460ProcessKDP::RefreshStateAfterStop () 461{ 462 // Let all threads recover from stopping and do any clean up based 463 // on the previous thread state (if any). 464 m_thread_list.RefreshStateAfterStop(); 465} 466 467Error 468ProcessKDP::DoHalt (bool &caused_stop) 469{ 470 Error error; 471 472 if (m_comm.IsRunning()) 473 { 474 if (m_destroy_in_process) 475 { 476 // If we are attemping to destroy, we need to not return an error to 477 // Halt or DoDestroy won't get called. 478 // We are also currently running, so send a process stopped event 479 SetPrivateState (eStateStopped); 480 } 481 else 482 { 483 error.SetErrorString ("KDP cannot interrupt a running kernel"); 484 } 485 } 486 return error; 487} 488 489Error 490ProcessKDP::DoDetach() 491{ 492 Error error; 493 Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 494 if (log) 495 log->Printf ("ProcessKDP::DoDetach()"); 496 497 if (m_comm.IsRunning()) 498 { 499 // We are running and we can't interrupt a running kernel, so we need 500 // to just close the connection to the kernel and hope for the best 501 } 502 else 503 { 504 DisableAllBreakpointSites (); 505 506 m_thread_list.DiscardThreadPlans(); 507 508 if (m_comm.IsConnected()) 509 { 510 511 m_comm.SendRequestDisconnect(); 512 513 size_t response_size = m_comm.Disconnect (); 514 if (log) 515 { 516 if (response_size) 517 log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully"); 518 else 519 log->PutCString ("ProcessKDP::DoDetach() detach packet send failed"); 520 } 521 } 522 } 523 StopAsyncThread (); 524 m_comm.Clear(); 525 526 SetPrivateState (eStateDetached); 527 ResumePrivateStateThread(); 528 529 //KillDebugserverProcess (); 530 return error; 531} 532 533Error 534ProcessKDP::DoDestroy () 535{ 536 // For KDP there really is no difference between destroy and detach 537 return DoDetach(); 538} 539 540//------------------------------------------------------------------ 541// Process Queries 542//------------------------------------------------------------------ 543 544bool 545ProcessKDP::IsAlive () 546{ 547 return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited; 548} 549 550//------------------------------------------------------------------ 551// Process Memory 552//------------------------------------------------------------------ 553size_t 554ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error) 555{ 556 if (m_comm.IsConnected()) 557 return m_comm.SendRequestReadMemory (addr, buf, size, error); 558 error.SetErrorString ("not connected"); 559 return 0; 560} 561 562size_t 563ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error) 564{ 565 if (m_comm.IsConnected()) 566 return m_comm.SendRequestWriteMemory (addr, buf, size, error); 567 error.SetErrorString ("not connected"); 568 return 0; 569} 570 571lldb::addr_t 572ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error) 573{ 574 error.SetErrorString ("memory allocation not suppported in kdp remote debugging"); 575 return LLDB_INVALID_ADDRESS; 576} 577 578Error 579ProcessKDP::DoDeallocateMemory (lldb::addr_t addr) 580{ 581 Error error; 582 error.SetErrorString ("memory deallocation not suppported in kdp remote debugging"); 583 return error; 584} 585 586Error 587ProcessKDP::EnableBreakpointSite (BreakpointSite *bp_site) 588{ 589 if (m_comm.LocalBreakpointsAreSupported ()) 590 { 591 Error error; 592 if (!bp_site->IsEnabled()) 593 { 594 if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) 595 { 596 bp_site->SetEnabled(true); 597 bp_site->SetType (BreakpointSite::eExternal); 598 } 599 else 600 { 601 error.SetErrorString ("KDP set breakpoint failed"); 602 } 603 } 604 return error; 605 } 606 return EnableSoftwareBreakpoint (bp_site); 607} 608 609Error 610ProcessKDP::DisableBreakpointSite (BreakpointSite *bp_site) 611{ 612 if (m_comm.LocalBreakpointsAreSupported ()) 613 { 614 Error error; 615 if (bp_site->IsEnabled()) 616 { 617 BreakpointSite::Type bp_type = bp_site->GetType(); 618 if (bp_type == BreakpointSite::eExternal) 619 { 620 if (m_destroy_in_process && m_comm.IsRunning()) 621 { 622 // We are trying to destroy our connection and we are running 623 bp_site->SetEnabled(false); 624 } 625 else 626 { 627 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress())) 628 bp_site->SetEnabled(false); 629 else 630 error.SetErrorString ("KDP remove breakpoint failed"); 631 } 632 } 633 else 634 { 635 error = DisableSoftwareBreakpoint (bp_site); 636 } 637 } 638 return error; 639 } 640 return DisableSoftwareBreakpoint (bp_site); 641} 642 643Error 644ProcessKDP::EnableWatchpoint (Watchpoint *wp, bool notify) 645{ 646 Error error; 647 error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); 648 return error; 649} 650 651Error 652ProcessKDP::DisableWatchpoint (Watchpoint *wp, bool notify) 653{ 654 Error error; 655 error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); 656 return error; 657} 658 659void 660ProcessKDP::Clear() 661{ 662 m_thread_list.Clear(); 663} 664 665Error 666ProcessKDP::DoSignal (int signo) 667{ 668 Error error; 669 error.SetErrorString ("sending signals is not suppported in kdp remote debugging"); 670 return error; 671} 672 673void 674ProcessKDP::Initialize() 675{ 676 static bool g_initialized = false; 677 678 if (g_initialized == false) 679 { 680 g_initialized = true; 681 PluginManager::RegisterPlugin (GetPluginNameStatic(), 682 GetPluginDescriptionStatic(), 683 CreateInstance); 684 685 Log::Callbacks log_callbacks = { 686 ProcessKDPLog::DisableLog, 687 ProcessKDPLog::EnableLog, 688 ProcessKDPLog::ListLogCategories 689 }; 690 691 Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks); 692 } 693} 694 695bool 696ProcessKDP::StartAsyncThread () 697{ 698 Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 699 700 if (log) 701 log->Printf ("ProcessKDP::StartAsyncThread ()"); 702 703 if (IS_VALID_LLDB_HOST_THREAD(m_async_thread)) 704 return true; 705 706 m_async_thread = Host::ThreadCreate ("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL); 707 return IS_VALID_LLDB_HOST_THREAD(m_async_thread); 708} 709 710void 711ProcessKDP::StopAsyncThread () 712{ 713 Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); 714 715 if (log) 716 log->Printf ("ProcessKDP::StopAsyncThread ()"); 717 718 m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit); 719 720 // Stop the stdio thread 721 if (IS_VALID_LLDB_HOST_THREAD(m_async_thread)) 722 { 723 Host::ThreadJoin (m_async_thread, NULL, NULL); 724 m_async_thread = LLDB_INVALID_HOST_THREAD; 725 } 726} 727 728 729void * 730ProcessKDP::AsyncThread (void *arg) 731{ 732 ProcessKDP *process = (ProcessKDP*) arg; 733 734 const lldb::pid_t pid = process->GetID(); 735 736 Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); 737 if (log) 738 log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid); 739 740 Listener listener ("ProcessKDP::AsyncThread"); 741 EventSP event_sp; 742 const uint32_t desired_event_mask = eBroadcastBitAsyncContinue | 743 eBroadcastBitAsyncThreadShouldExit; 744 745 746 if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask) 747 { 748 bool done = false; 749 while (!done) 750 { 751 if (log) 752 log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", 753 pid); 754 if (listener.WaitForEvent (NULL, event_sp)) 755 { 756 uint32_t event_type = event_sp->GetType(); 757 if (log) 758 log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") Got an event of type: %d...", 759 pid, 760 event_type); 761 762 // When we are running, poll for 1 second to try and get an exception 763 // to indicate the process has stopped. If we don't get one, check to 764 // make sure no one asked us to exit 765 bool is_running = false; 766 DataExtractor exc_reply_packet; 767 do 768 { 769 switch (event_type) 770 { 771 case eBroadcastBitAsyncContinue: 772 { 773 is_running = true; 774 if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 1 * USEC_PER_SEC)) 775 { 776 ThreadSP thread_sp (process->GetKernelThread(process->GetThreadList(), process->GetThreadList())); 777 thread_sp->GetRegisterContext()->InvalidateAllRegisters(); 778 static_cast<ThreadKDP *>(thread_sp.get())->SetStopInfoFrom_KDP_EXCEPTION (exc_reply_packet); 779 780 // TODO: parse the stop reply packet 781 is_running = false; 782 process->SetPrivateState(eStateStopped); 783 } 784 else 785 { 786 // Check to see if we are supposed to exit. There is no way to 787 // interrupt a running kernel, so all we can do is wait for an 788 // exception or detach... 789 if (listener.GetNextEvent(event_sp)) 790 { 791 // We got an event, go through the loop again 792 event_type = event_sp->GetType(); 793 } 794 } 795 } 796 break; 797 798 case eBroadcastBitAsyncThreadShouldExit: 799 if (log) 800 log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...", 801 pid); 802 done = true; 803 is_running = false; 804 break; 805 806 default: 807 if (log) 808 log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got unknown event 0x%8.8x", 809 pid, 810 event_type); 811 done = true; 812 is_running = false; 813 break; 814 } 815 } while (is_running); 816 } 817 else 818 { 819 if (log) 820 log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false", 821 pid); 822 done = true; 823 } 824 } 825 } 826 827 if (log) 828 log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread exiting...", 829 arg, 830 pid); 831 832 process->m_async_thread = LLDB_INVALID_HOST_THREAD; 833 return NULL; 834} 835 836 837class CommandObjectProcessKDPPacketSend : public CommandObjectParsed 838{ 839private: 840 841 OptionGroupOptions m_option_group; 842 OptionGroupUInt64 m_command_byte; 843 OptionGroupString m_packet_data; 844 845 virtual Options * 846 GetOptions () 847 { 848 return &m_option_group; 849 } 850 851 852public: 853 CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter) : 854 CommandObjectParsed (interpreter, 855 "process plugin packet send", 856 "Send a custom packet through the KDP protocol by specifying the command byte and the packet payload data. A packet will be sent with a correct header and payload, and the raw result bytes will be displayed as a string value. ", 857 NULL), 858 m_option_group (interpreter), 859 m_command_byte(LLDB_OPT_SET_1, true , "command", 'c', 0, eArgTypeNone, "Specify the command byte to use when sending the KDP request packet.", 0), 860 m_packet_data (LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone, "Specify packet payload bytes as a hex ASCII string with no spaces or hex prefixes.", NULL) 861 { 862 m_option_group.Append (&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 863 m_option_group.Append (&m_packet_data , LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 864 m_option_group.Finalize(); 865 } 866 867 ~CommandObjectProcessKDPPacketSend () 868 { 869 } 870 871 bool 872 DoExecute (Args& command, CommandReturnObject &result) 873 { 874 const size_t argc = command.GetArgumentCount(); 875 if (argc == 0) 876 { 877 if (!m_command_byte.GetOptionValue().OptionWasSet()) 878 { 879 result.AppendError ("the --command option must be set to a valid command byte"); 880 result.SetStatus (eReturnStatusFailed); 881 } 882 else 883 { 884 const uint64_t command_byte = m_command_byte.GetOptionValue().GetUInt64Value(0); 885 if (command_byte > 0 && command_byte <= UINT8_MAX) 886 { 887 ProcessKDP *process = (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr(); 888 if (process) 889 { 890 const StateType state = process->GetState(); 891 892 if (StateIsStoppedState (state, true)) 893 { 894 std::vector<uint8_t> payload_bytes; 895 const char *ascii_hex_bytes_cstr = m_packet_data.GetOptionValue().GetCurrentValue(); 896 if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) 897 { 898 StringExtractor extractor(ascii_hex_bytes_cstr); 899 const size_t ascii_hex_bytes_cstr_len = extractor.GetStringRef().size(); 900 if (ascii_hex_bytes_cstr_len & 1) 901 { 902 result.AppendErrorWithFormat ("payload data must contain an even number of ASCII hex characters: '%s'", ascii_hex_bytes_cstr); 903 result.SetStatus (eReturnStatusFailed); 904 return false; 905 } 906 payload_bytes.resize(ascii_hex_bytes_cstr_len/2); 907 if (extractor.GetHexBytes(&payload_bytes[0], payload_bytes.size(), '\xdd') != payload_bytes.size()) 908 { 909 result.AppendErrorWithFormat ("payload data must only contain ASCII hex characters (no spaces or hex prefixes): '%s'", ascii_hex_bytes_cstr); 910 result.SetStatus (eReturnStatusFailed); 911 return false; 912 } 913 } 914 Error error; 915 DataExtractor reply; 916 process->GetCommunication().SendRawRequest (command_byte, 917 payload_bytes.empty() ? NULL : payload_bytes.data(), 918 payload_bytes.size(), 919 reply, 920 error); 921 922 if (error.Success()) 923 { 924 // Copy the binary bytes into a hex ASCII string for the result 925 StreamString packet; 926 packet.PutBytesAsRawHex8(reply.GetDataStart(), 927 reply.GetByteSize(), 928 lldb::endian::InlHostByteOrder(), 929 lldb::endian::InlHostByteOrder()); 930 result.AppendMessage(packet.GetString().c_str()); 931 result.SetStatus (eReturnStatusSuccessFinishResult); 932 return true; 933 } 934 else 935 { 936 const char *error_cstr = error.AsCString(); 937 if (error_cstr && error_cstr[0]) 938 result.AppendError (error_cstr); 939 else 940 result.AppendErrorWithFormat ("unknown error 0x%8.8x", error.GetError()); 941 result.SetStatus (eReturnStatusFailed); 942 return false; 943 } 944 } 945 else 946 { 947 result.AppendErrorWithFormat ("process must be stopped in order to send KDP packets, state is %s", StateAsCString (state)); 948 result.SetStatus (eReturnStatusFailed); 949 } 950 } 951 else 952 { 953 result.AppendError ("invalid process"); 954 result.SetStatus (eReturnStatusFailed); 955 } 956 } 957 else 958 { 959 result.AppendErrorWithFormat ("invalid command byte 0x%" PRIx64 ", valid values are 1 - 255", command_byte); 960 result.SetStatus (eReturnStatusFailed); 961 } 962 } 963 } 964 else 965 { 966 result.AppendErrorWithFormat ("'%s' takes no arguments, only options.", m_cmd_name.c_str()); 967 result.SetStatus (eReturnStatusFailed); 968 } 969 return false; 970 } 971}; 972 973class CommandObjectProcessKDPPacket : public CommandObjectMultiword 974{ 975private: 976 977public: 978 CommandObjectProcessKDPPacket(CommandInterpreter &interpreter) : 979 CommandObjectMultiword (interpreter, 980 "process plugin packet", 981 "Commands that deal with KDP remote packets.", 982 NULL) 983 { 984 LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessKDPPacketSend (interpreter))); 985 } 986 987 ~CommandObjectProcessKDPPacket () 988 { 989 } 990}; 991 992class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword 993{ 994public: 995 CommandObjectMultiwordProcessKDP (CommandInterpreter &interpreter) : 996 CommandObjectMultiword (interpreter, 997 "process plugin", 998 "A set of commands for operating on a ProcessKDP process.", 999 "process plugin <subcommand> [<subcommand-options>]") 1000 { 1001 LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessKDPPacket (interpreter))); 1002 } 1003 1004 ~CommandObjectMultiwordProcessKDP () 1005 { 1006 } 1007}; 1008 1009CommandObject * 1010ProcessKDP::GetPluginCommandObject() 1011{ 1012 if (!m_command_sp) 1013 m_command_sp.reset (new CommandObjectMultiwordProcessKDP (GetTarget().GetDebugger().GetCommandInterpreter())); 1014 return m_command_sp.get(); 1015} 1016 1017