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 
44 using namespace lldb;
45 using namespace lldb_private;
46 
47 const char *
48 ProcessKDP::GetPluginNameStatic()
49 {
50     return "kdp-remote";
51 }
52 
53 const char *
54 ProcessKDP::GetPluginDescriptionStatic()
55 {
56     return "KDP Remote protocol based debugging plug-in for darwin kernel debugging.";
57 }
58 
59 void
60 ProcessKDP::Terminate()
61 {
62     PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance);
63 }
64 
65 
66 lldb::ProcessSP
67 ProcessKDP::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 
77 bool
78 ProcessKDP::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 //----------------------------------------------------------------------
112 ProcessKDP::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 //----------------------------------------------------------------------
128 ProcessKDP::~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 //----------------------------------------------------------------------
141 const char *
142 ProcessKDP::GetPluginName()
143 {
144     return "Process debugging plug-in that uses the Darwin KDP remote protocol";
145 }
146 
147 const char *
148 ProcessKDP::GetShortPluginName()
149 {
150     return GetPluginNameStatic();
151 }
152 
153 uint32_t
154 ProcessKDP::GetPluginVersion()
155 {
156     return 1;
157 }
158 
159 Error
160 ProcessKDP::WillLaunch (Module* module)
161 {
162     Error error;
163     error.SetErrorString ("launching not supported in kdp-remote plug-in");
164     return error;
165 }
166 
167 Error
168 ProcessKDP::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 
175 Error
176 ProcessKDP::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 
183 Error
184 ProcessKDP::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::unique_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 //----------------------------------------------------------------------
298 Error
299 ProcessKDP::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 
308 Error
309 ProcessKDP::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 
316 Error
317 ProcessKDP::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 
324 Error
325 ProcessKDP::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 
333 void
334 ProcessKDP::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 
345 addr_t
346 ProcessKDP::GetImageInfoAddress()
347 {
348     return m_kernel_load_addr;
349 }
350 
351 lldb_private::DynamicLoader *
352 ProcessKDP::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 
359 Error
360 ProcessKDP::WillResume ()
361 {
362     return Error();
363 }
364 
365 Error
366 ProcessKDP::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                 {
390                     lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());
391 
392                     if (reg_ctx_sp)
393                     {
394                         reg_ctx_sp->HardwareSingleStep (true);
395                         resume = true;
396                     }
397                     else
398                     {
399                         error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
400                     }
401                 }
402                 break;
403 
404             case eStateRunning:
405                 {
406                     lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());
407 
408                         if (reg_ctx_sp)
409                         {
410                             reg_ctx_sp->HardwareSingleStep (false);
411                             resume = true;
412                         }
413                         else
414                         {
415                             error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
416                         }
417                 }
418                 break;
419 
420             default:
421                 // The only valid thread resume states are listed above
422                 assert (!"invalid thread resume state");
423                 break;
424         }
425     }
426 
427     if (resume)
428     {
429         if (log)
430             log->Printf ("ProcessKDP::DoResume () sending resume");
431 
432         if (m_comm.SendRequestResume ())
433         {
434             m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue);
435             SetPrivateState(eStateRunning);
436         }
437         else
438             error.SetErrorString ("KDP resume failed");
439     }
440     else
441     {
442         error.SetErrorString ("kernel thread is suspended");
443     }
444 
445     return error;
446 }
447 
448 lldb::ThreadSP
449 ProcessKDP::GetKernelThread(ThreadList &old_thread_list, ThreadList &new_thread_list)
450 {
451     // KDP only tells us about one thread/core. Any other threads will usually
452     // be the ones that are read from memory by the OS plug-ins.
453     const lldb::tid_t kernel_tid = 1;
454     ThreadSP thread_sp (old_thread_list.FindThreadByID (kernel_tid, false));
455     if (!thread_sp)
456         thread_sp.reset(new ThreadKDP (*this, kernel_tid));
457     new_thread_list.AddThread(thread_sp);
458     return thread_sp;
459 }
460 
461 
462 
463 
464 bool
465 ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
466 {
467     // locker will keep a mutex locked until it goes out of scope
468     Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
469     if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
470         log->Printf ("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
471 
472     // Even though there is a CPU mask, it doesn't mean we can see each CPU
473     // indivudually, there is really only one. Lets call this thread 1.
474     GetKernelThread (old_thread_list, new_thread_list);
475 
476     return new_thread_list.GetSize(false) > 0;
477 }
478 
479 void
480 ProcessKDP::RefreshStateAfterStop ()
481 {
482     // Let all threads recover from stopping and do any clean up based
483     // on the previous thread state (if any).
484     m_thread_list.RefreshStateAfterStop();
485 }
486 
487 Error
488 ProcessKDP::DoHalt (bool &caused_stop)
489 {
490     Error error;
491 
492     if (m_comm.IsRunning())
493     {
494         if (m_destroy_in_process)
495         {
496             // If we are attemping to destroy, we need to not return an error to
497             // Halt or DoDestroy won't get called.
498             // We are also currently running, so send a process stopped event
499             SetPrivateState (eStateStopped);
500         }
501         else
502         {
503             error.SetErrorString ("KDP cannot interrupt a running kernel");
504         }
505     }
506     return error;
507 }
508 
509 Error
510 ProcessKDP::DoDetach(bool keep_stopped)
511 {
512     Error error;
513     Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
514     if (log)
515         log->Printf ("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
516 
517     if (m_comm.IsRunning())
518     {
519         // We are running and we can't interrupt a running kernel, so we need
520         // to just close the connection to the kernel and hope for the best
521     }
522     else
523     {
524         DisableAllBreakpointSites ();
525 
526         m_thread_list.DiscardThreadPlans();
527 
528         // If we are going to keep the target stopped, then don't send the disconnect message.
529         if (!keep_stopped && m_comm.IsConnected())
530         {
531 
532             m_comm.SendRequestDisconnect();
533 
534             size_t response_size = m_comm.Disconnect ();
535             if (log)
536             {
537                 if (response_size)
538                     log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
539                 else
540                     log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
541             }
542         }
543     }
544     StopAsyncThread ();
545     m_comm.Clear();
546 
547     SetPrivateState (eStateDetached);
548     ResumePrivateStateThread();
549 
550     //KillDebugserverProcess ();
551     return error;
552 }
553 
554 Error
555 ProcessKDP::DoDestroy ()
556 {
557     // For KDP there really is no difference between destroy and detach
558     bool keep_stopped = false;
559     return DoDetach(keep_stopped);
560 }
561 
562 //------------------------------------------------------------------
563 // Process Queries
564 //------------------------------------------------------------------
565 
566 bool
567 ProcessKDP::IsAlive ()
568 {
569     return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
570 }
571 
572 //------------------------------------------------------------------
573 // Process Memory
574 //------------------------------------------------------------------
575 size_t
576 ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
577 {
578     if (m_comm.IsConnected())
579         return m_comm.SendRequestReadMemory (addr, buf, size, error);
580     error.SetErrorString ("not connected");
581     return 0;
582 }
583 
584 size_t
585 ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
586 {
587     if (m_comm.IsConnected())
588         return m_comm.SendRequestWriteMemory (addr, buf, size, error);
589     error.SetErrorString ("not connected");
590     return 0;
591 }
592 
593 lldb::addr_t
594 ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
595 {
596     error.SetErrorString ("memory allocation not suppported in kdp remote debugging");
597     return LLDB_INVALID_ADDRESS;
598 }
599 
600 Error
601 ProcessKDP::DoDeallocateMemory (lldb::addr_t addr)
602 {
603     Error error;
604     error.SetErrorString ("memory deallocation not suppported in kdp remote debugging");
605     return error;
606 }
607 
608 Error
609 ProcessKDP::EnableBreakpointSite (BreakpointSite *bp_site)
610 {
611     if (m_comm.LocalBreakpointsAreSupported ())
612     {
613         Error error;
614         if (!bp_site->IsEnabled())
615         {
616             if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress()))
617             {
618                 bp_site->SetEnabled(true);
619                 bp_site->SetType (BreakpointSite::eExternal);
620             }
621             else
622             {
623                 error.SetErrorString ("KDP set breakpoint failed");
624             }
625         }
626         return error;
627     }
628     return EnableSoftwareBreakpoint (bp_site);
629 }
630 
631 Error
632 ProcessKDP::DisableBreakpointSite (BreakpointSite *bp_site)
633 {
634     if (m_comm.LocalBreakpointsAreSupported ())
635     {
636         Error error;
637         if (bp_site->IsEnabled())
638         {
639             BreakpointSite::Type bp_type = bp_site->GetType();
640             if (bp_type == BreakpointSite::eExternal)
641             {
642                 if (m_destroy_in_process && m_comm.IsRunning())
643                 {
644                     // We are trying to destroy our connection and we are running
645                     bp_site->SetEnabled(false);
646                 }
647                 else
648                 {
649                     if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
650                         bp_site->SetEnabled(false);
651                     else
652                         error.SetErrorString ("KDP remove breakpoint failed");
653                 }
654             }
655             else
656             {
657                 error = DisableSoftwareBreakpoint (bp_site);
658             }
659         }
660         return error;
661     }
662     return DisableSoftwareBreakpoint (bp_site);
663 }
664 
665 Error
666 ProcessKDP::EnableWatchpoint (Watchpoint *wp, bool notify)
667 {
668     Error error;
669     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
670     return error;
671 }
672 
673 Error
674 ProcessKDP::DisableWatchpoint (Watchpoint *wp, bool notify)
675 {
676     Error error;
677     error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
678     return error;
679 }
680 
681 void
682 ProcessKDP::Clear()
683 {
684     m_thread_list.Clear();
685 }
686 
687 Error
688 ProcessKDP::DoSignal (int signo)
689 {
690     Error error;
691     error.SetErrorString ("sending signals is not suppported in kdp remote debugging");
692     return error;
693 }
694 
695 void
696 ProcessKDP::Initialize()
697 {
698     static bool g_initialized = false;
699 
700     if (g_initialized == false)
701     {
702         g_initialized = true;
703         PluginManager::RegisterPlugin (GetPluginNameStatic(),
704                                        GetPluginDescriptionStatic(),
705                                        CreateInstance);
706 
707         Log::Callbacks log_callbacks = {
708             ProcessKDPLog::DisableLog,
709             ProcessKDPLog::EnableLog,
710             ProcessKDPLog::ListLogCategories
711         };
712 
713         Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks);
714     }
715 }
716 
717 bool
718 ProcessKDP::StartAsyncThread ()
719 {
720     Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
721 
722     if (log)
723         log->Printf ("ProcessKDP::StartAsyncThread ()");
724 
725     if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
726         return true;
727 
728     m_async_thread = Host::ThreadCreate ("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
729     return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
730 }
731 
732 void
733 ProcessKDP::StopAsyncThread ()
734 {
735     Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
736 
737     if (log)
738         log->Printf ("ProcessKDP::StopAsyncThread ()");
739 
740     m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
741 
742     // Stop the stdio thread
743     if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
744     {
745         Host::ThreadJoin (m_async_thread, NULL, NULL);
746         m_async_thread = LLDB_INVALID_HOST_THREAD;
747     }
748 }
749 
750 
751 void *
752 ProcessKDP::AsyncThread (void *arg)
753 {
754     ProcessKDP *process = (ProcessKDP*) arg;
755 
756     const lldb::pid_t pid = process->GetID();
757 
758     Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
759     if (log)
760         log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid);
761 
762     Listener listener ("ProcessKDP::AsyncThread");
763     EventSP event_sp;
764     const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
765                                         eBroadcastBitAsyncThreadShouldExit;
766 
767 
768     if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
769     {
770         bool done = false;
771         while (!done)
772         {
773             if (log)
774                 log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...",
775                              pid);
776             if (listener.WaitForEvent (NULL, event_sp))
777             {
778                 uint32_t event_type = event_sp->GetType();
779                 if (log)
780                     log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") Got an event of type: %d...",
781                                  pid,
782                                  event_type);
783 
784                 // When we are running, poll for 1 second to try and get an exception
785                 // to indicate the process has stopped. If we don't get one, check to
786                 // make sure no one asked us to exit
787                 bool is_running = false;
788                 DataExtractor exc_reply_packet;
789                 do
790                 {
791                     switch (event_type)
792                     {
793                     case eBroadcastBitAsyncContinue:
794                         {
795                             is_running = true;
796                             if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 1 * USEC_PER_SEC))
797                             {
798                                 ThreadSP thread_sp (process->GetKernelThread(process->GetThreadList(), process->GetThreadList()));
799                                 if (thread_sp)
800                                 {
801                                     lldb::RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext());
802                                     if (reg_ctx_sp)
803                                         reg_ctx_sp->InvalidateAllRegisters();
804                                     static_cast<ThreadKDP *>(thread_sp.get())->SetStopInfoFrom_KDP_EXCEPTION (exc_reply_packet);
805                                 }
806 
807                                 // TODO: parse the stop reply packet
808                                 is_running = false;
809                                 process->SetPrivateState(eStateStopped);
810                             }
811                             else
812                             {
813                                 // Check to see if we are supposed to exit. There is no way to
814                                 // interrupt a running kernel, so all we can do is wait for an
815                                 // exception or detach...
816                                 if (listener.GetNextEvent(event_sp))
817                                 {
818                                     // We got an event, go through the loop again
819                                     event_type = event_sp->GetType();
820                                 }
821                             }
822                         }
823                         break;
824 
825                     case eBroadcastBitAsyncThreadShouldExit:
826                         if (log)
827                             log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...",
828                                          pid);
829                         done = true;
830                         is_running = false;
831                         break;
832 
833                     default:
834                         if (log)
835                             log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got unknown event 0x%8.8x",
836                                          pid,
837                                          event_type);
838                         done = true;
839                         is_running = false;
840                         break;
841                     }
842                 } while (is_running);
843             }
844             else
845             {
846                 if (log)
847                     log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false",
848                                  pid);
849                 done = true;
850             }
851         }
852     }
853 
854     if (log)
855         log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread exiting...",
856                      arg,
857                      pid);
858 
859     process->m_async_thread = LLDB_INVALID_HOST_THREAD;
860     return NULL;
861 }
862 
863 
864 class CommandObjectProcessKDPPacketSend : public CommandObjectParsed
865 {
866 private:
867 
868     OptionGroupOptions m_option_group;
869     OptionGroupUInt64 m_command_byte;
870     OptionGroupString m_packet_data;
871 
872     virtual Options *
873     GetOptions ()
874     {
875         return &m_option_group;
876     }
877 
878 
879 public:
880     CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter) :
881         CommandObjectParsed (interpreter,
882                              "process plugin packet send",
883                              "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. ",
884                              NULL),
885         m_option_group (interpreter),
886         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),
887         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)
888     {
889         m_option_group.Append (&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
890         m_option_group.Append (&m_packet_data , LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
891         m_option_group.Finalize();
892     }
893 
894     ~CommandObjectProcessKDPPacketSend ()
895     {
896     }
897 
898     bool
899     DoExecute (Args& command, CommandReturnObject &result)
900     {
901         const size_t argc = command.GetArgumentCount();
902         if (argc == 0)
903         {
904             if (!m_command_byte.GetOptionValue().OptionWasSet())
905             {
906                 result.AppendError ("the --command option must be set to a valid command byte");
907                 result.SetStatus (eReturnStatusFailed);
908             }
909             else
910             {
911                 const uint64_t command_byte = m_command_byte.GetOptionValue().GetUInt64Value(0);
912                 if (command_byte > 0 && command_byte <= UINT8_MAX)
913                 {
914                     ProcessKDP *process = (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
915                     if (process)
916                     {
917                         const StateType state = process->GetState();
918 
919                         if (StateIsStoppedState (state, true))
920                         {
921                             std::vector<uint8_t> payload_bytes;
922                             const char *ascii_hex_bytes_cstr = m_packet_data.GetOptionValue().GetCurrentValue();
923                             if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0])
924                             {
925                                 StringExtractor extractor(ascii_hex_bytes_cstr);
926                                 const size_t ascii_hex_bytes_cstr_len = extractor.GetStringRef().size();
927                                 if (ascii_hex_bytes_cstr_len & 1)
928                                 {
929                                     result.AppendErrorWithFormat ("payload data must contain an even number of ASCII hex characters: '%s'", ascii_hex_bytes_cstr);
930                                     result.SetStatus (eReturnStatusFailed);
931                                     return false;
932                                 }
933                                 payload_bytes.resize(ascii_hex_bytes_cstr_len/2);
934                                 if (extractor.GetHexBytes(&payload_bytes[0], payload_bytes.size(), '\xdd') != payload_bytes.size())
935                                 {
936                                     result.AppendErrorWithFormat ("payload data must only contain ASCII hex characters (no spaces or hex prefixes): '%s'", ascii_hex_bytes_cstr);
937                                     result.SetStatus (eReturnStatusFailed);
938                                     return false;
939                                 }
940                             }
941                             Error error;
942                             DataExtractor reply;
943                             process->GetCommunication().SendRawRequest (command_byte,
944                                                                         payload_bytes.empty() ? NULL : payload_bytes.data(),
945                                                                         payload_bytes.size(),
946                                                                         reply,
947                                                                         error);
948 
949                             if (error.Success())
950                             {
951                                 // Copy the binary bytes into a hex ASCII string for the result
952                                 StreamString packet;
953                                 packet.PutBytesAsRawHex8(reply.GetDataStart(),
954                                                          reply.GetByteSize(),
955                                                          lldb::endian::InlHostByteOrder(),
956                                                          lldb::endian::InlHostByteOrder());
957                                 result.AppendMessage(packet.GetString().c_str());
958                                 result.SetStatus (eReturnStatusSuccessFinishResult);
959                                 return true;
960                             }
961                             else
962                             {
963                                 const char *error_cstr = error.AsCString();
964                                 if (error_cstr && error_cstr[0])
965                                     result.AppendError (error_cstr);
966                                 else
967                                     result.AppendErrorWithFormat ("unknown error 0x%8.8x", error.GetError());
968                                 result.SetStatus (eReturnStatusFailed);
969                                 return false;
970                             }
971                         }
972                         else
973                         {
974                             result.AppendErrorWithFormat ("process must be stopped in order to send KDP packets, state is %s", StateAsCString (state));
975                             result.SetStatus (eReturnStatusFailed);
976                         }
977                     }
978                     else
979                     {
980                         result.AppendError ("invalid process");
981                         result.SetStatus (eReturnStatusFailed);
982                     }
983                 }
984                 else
985                 {
986                     result.AppendErrorWithFormat ("invalid command byte 0x%" PRIx64 ", valid values are 1 - 255", command_byte);
987                     result.SetStatus (eReturnStatusFailed);
988                 }
989             }
990         }
991         else
992         {
993             result.AppendErrorWithFormat ("'%s' takes no arguments, only options.", m_cmd_name.c_str());
994             result.SetStatus (eReturnStatusFailed);
995         }
996         return false;
997     }
998 };
999 
1000 class CommandObjectProcessKDPPacket : public CommandObjectMultiword
1001 {
1002 private:
1003 
1004 public:
1005     CommandObjectProcessKDPPacket(CommandInterpreter &interpreter) :
1006     CommandObjectMultiword (interpreter,
1007                             "process plugin packet",
1008                             "Commands that deal with KDP remote packets.",
1009                             NULL)
1010     {
1011         LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessKDPPacketSend (interpreter)));
1012     }
1013 
1014     ~CommandObjectProcessKDPPacket ()
1015     {
1016     }
1017 };
1018 
1019 class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword
1020 {
1021 public:
1022     CommandObjectMultiwordProcessKDP (CommandInterpreter &interpreter) :
1023     CommandObjectMultiword (interpreter,
1024                             "process plugin",
1025                             "A set of commands for operating on a ProcessKDP process.",
1026                             "process plugin <subcommand> [<subcommand-options>]")
1027     {
1028         LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessKDPPacket    (interpreter)));
1029     }
1030 
1031     ~CommandObjectMultiwordProcessKDP ()
1032     {
1033     }
1034 };
1035 
1036 CommandObject *
1037 ProcessKDP::GetPluginCommandObject()
1038 {
1039     if (!m_command_sp)
1040         m_command_sp.reset (new CommandObjectMultiwordProcessKDP (GetTarget().GetDebugger().GetCommandInterpreter()));
1041     return m_command_sp.get();
1042 }
1043 
1044