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