Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / source / Plugins / Process / MacOSX-Kernel / ProcessKDP.cpp
blob0d1caf4d7318b72bd79483227f9d59bc45e53c99
1 //===-- ProcessKDP.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include <cerrno>
10 #include <cstdlib>
12 #include <memory>
13 #include <mutex>
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/ModuleSpec.h"
18 #include "lldb/Core/PluginManager.h"
19 #include "lldb/Host/ConnectionFileDescriptor.h"
20 #include "lldb/Host/Host.h"
21 #include "lldb/Host/ThreadLauncher.h"
22 #include "lldb/Host/common/TCPSocket.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Interpreter/CommandObject.h"
25 #include "lldb/Interpreter/CommandObjectMultiword.h"
26 #include "lldb/Interpreter/CommandReturnObject.h"
27 #include "lldb/Interpreter/OptionGroupString.h"
28 #include "lldb/Interpreter/OptionGroupUInt64.h"
29 #include "lldb/Interpreter/OptionValueProperties.h"
30 #include "lldb/Symbol/LocateSymbolFile.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 #include "lldb/Utility/LLDBLog.h"
36 #include "lldb/Utility/Log.h"
37 #include "lldb/Utility/State.h"
38 #include "lldb/Utility/StringExtractor.h"
39 #include "lldb/Utility/UUID.h"
41 #include "llvm/Support/Threading.h"
43 #define USEC_PER_SEC 1000000
45 #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
46 #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
47 #include "ProcessKDP.h"
48 #include "ProcessKDPLog.h"
49 #include "ThreadKDP.h"
51 using namespace lldb;
52 using namespace lldb_private;
54 LLDB_PLUGIN_DEFINE_ADV(ProcessKDP, ProcessMacOSXKernel)
56 namespace {
58 #define LLDB_PROPERTIES_processkdp
59 #include "ProcessKDPProperties.inc"
61 enum {
62 #define LLDB_PROPERTIES_processkdp
63 #include "ProcessKDPPropertiesEnum.inc"
66 class PluginProperties : public Properties {
67 public:
68 static llvm::StringRef GetSettingName() {
69 return ProcessKDP::GetPluginNameStatic();
72 PluginProperties() : Properties() {
73 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
74 m_collection_sp->Initialize(g_processkdp_properties);
77 ~PluginProperties() override = default;
79 uint64_t GetPacketTimeout() {
80 const uint32_t idx = ePropertyKDPPacketTimeout;
81 return GetPropertyAtIndexAs<uint64_t>(
82 idx, g_processkdp_properties[idx].default_uint_value);
86 } // namespace
88 static PluginProperties &GetGlobalPluginProperties() {
89 static PluginProperties g_settings;
90 return g_settings;
93 static const lldb::tid_t g_kernel_tid = 1;
95 llvm::StringRef ProcessKDP::GetPluginDescriptionStatic() {
96 return "KDP Remote protocol based debugging plug-in for darwin kernel "
97 "debugging.";
100 void ProcessKDP::Terminate() {
101 PluginManager::UnregisterPlugin(ProcessKDP::CreateInstance);
104 lldb::ProcessSP ProcessKDP::CreateInstance(TargetSP target_sp,
105 ListenerSP listener_sp,
106 const FileSpec *crash_file_path,
107 bool can_connect) {
108 lldb::ProcessSP process_sp;
109 if (crash_file_path == NULL)
110 process_sp = std::make_shared<ProcessKDP>(target_sp, listener_sp);
111 return process_sp;
114 bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
115 if (plugin_specified_by_name)
116 return true;
118 // For now we are just making sure the file exists for a given module
119 Module *exe_module = target_sp->GetExecutableModulePointer();
120 if (exe_module) {
121 const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
122 switch (triple_ref.getOS()) {
123 case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for
124 // iOS, but accept darwin just in case
125 case llvm::Triple::MacOSX: // For desktop targets
126 case llvm::Triple::IOS: // For arm targets
127 case llvm::Triple::TvOS:
128 case llvm::Triple::WatchOS:
129 if (triple_ref.getVendor() == llvm::Triple::Apple) {
130 ObjectFile *exe_objfile = exe_module->GetObjectFile();
131 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
132 exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
133 return true;
135 break;
137 default:
138 break;
141 return false;
144 // ProcessKDP constructor
145 ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp)
146 : Process(target_sp, listener_sp),
147 m_comm("lldb.process.kdp-remote.communication"),
148 m_async_broadcaster(NULL, "lldb.process.kdp-remote.async-broadcaster"),
149 m_kernel_load_addr(LLDB_INVALID_ADDRESS), m_command_sp(),
150 m_kernel_thread_wp() {
151 m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
152 "async thread should exit");
153 m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
154 "async thread continue");
155 const uint64_t timeout_seconds =
156 GetGlobalPluginProperties().GetPacketTimeout();
157 if (timeout_seconds > 0)
158 m_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
161 // Destructor
162 ProcessKDP::~ProcessKDP() {
163 Clear();
164 // We need to call finalize on the process before destroying ourselves to
165 // make sure all of the broadcaster cleanup goes as planned. If we destruct
166 // this class, then Process::~Process() might have problems trying to fully
167 // destroy the broadcaster.
168 Finalize();
171 Status ProcessKDP::DoWillLaunch(Module *module) {
172 Status error;
173 error.SetErrorString("launching not supported in kdp-remote plug-in");
174 return error;
177 Status ProcessKDP::DoWillAttachToProcessWithID(lldb::pid_t pid) {
178 Status error;
179 error.SetErrorString(
180 "attaching to a by process ID not supported in kdp-remote plug-in");
181 return error;
184 Status ProcessKDP::DoWillAttachToProcessWithName(const char *process_name,
185 bool wait_for_launch) {
186 Status error;
187 error.SetErrorString(
188 "attaching to a by process name not supported in kdp-remote plug-in");
189 return error;
192 bool ProcessKDP::GetHostArchitecture(ArchSpec &arch) {
193 uint32_t cpu = m_comm.GetCPUType();
194 if (cpu) {
195 uint32_t sub = m_comm.GetCPUSubtype();
196 arch.SetArchitecture(eArchTypeMachO, cpu, sub);
197 // Leave architecture vendor as unspecified unknown
198 arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);
199 arch.GetTriple().setVendorName(llvm::StringRef());
200 return true;
202 arch.Clear();
203 return false;
206 Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) {
207 Status error;
209 // Don't let any JIT happen when doing KDP as we can't allocate memory and we
210 // don't want to be mucking with threads that might already be handling
211 // exceptions
212 SetCanJIT(false);
214 if (remote_url.empty()) {
215 error.SetErrorStringWithFormat("empty connection URL");
216 return error;
219 std::unique_ptr<ConnectionFileDescriptor> conn_up(
220 new ConnectionFileDescriptor());
221 if (conn_up) {
222 // Only try once for now.
223 // TODO: check if we should be retrying?
224 const uint32_t max_retry_count = 1;
225 for (uint32_t retry_count = 0; retry_count < max_retry_count;
226 ++retry_count) {
227 if (conn_up->Connect(remote_url, &error) == eConnectionStatusSuccess)
228 break;
229 usleep(100000);
233 if (conn_up->IsConnected()) {
234 const TCPSocket &socket =
235 static_cast<const TCPSocket &>(*conn_up->GetReadObject());
236 const uint16_t reply_port = socket.GetLocalPortNumber();
238 if (reply_port != 0) {
239 m_comm.SetConnection(std::move(conn_up));
241 if (m_comm.SendRequestReattach(reply_port)) {
242 if (m_comm.SendRequestConnect(reply_port, reply_port,
243 "Greetings from LLDB...")) {
244 m_comm.GetVersion();
246 Target &target = GetTarget();
247 ArchSpec kernel_arch;
248 // The host architecture
249 GetHostArchitecture(kernel_arch);
250 ArchSpec target_arch = target.GetArchitecture();
251 // Merge in any unspecified stuff into the target architecture in
252 // case the target arch isn't set at all or incompletely.
253 target_arch.MergeFrom(kernel_arch);
254 target.SetArchitecture(target_arch);
256 /* Get the kernel's UUID and load address via KDP_KERNELVERSION
257 * packet. */
258 /* An EFI kdp session has neither UUID nor load address. */
260 UUID kernel_uuid = m_comm.GetUUID();
261 addr_t kernel_load_addr = m_comm.GetLoadAddress();
263 if (m_comm.RemoteIsEFI()) {
264 // Select an invalid plugin name for the dynamic loader so one
265 // doesn't get used since EFI does its own manual loading via
266 // python scripting
267 m_dyld_plugin_name = "none";
269 if (kernel_uuid.IsValid()) {
270 // If EFI passed in a UUID= try to lookup UUID The slide will not
271 // be provided. But the UUID lookup will be used to launch EFI
272 // debug scripts from the dSYM, that can load all of the symbols.
273 ModuleSpec module_spec;
274 module_spec.GetUUID() = kernel_uuid;
275 module_spec.GetArchitecture() = target.GetArchitecture();
277 // Lookup UUID locally, before attempting dsymForUUID like action
278 FileSpecList search_paths =
279 Target::GetDefaultDebugFileSearchPaths();
280 module_spec.GetSymbolFileSpec() =
281 Symbols::LocateExecutableSymbolFile(module_spec,
282 search_paths);
283 if (module_spec.GetSymbolFileSpec()) {
284 ModuleSpec executable_module_spec =
285 Symbols::LocateExecutableObjectFile(module_spec);
286 if (FileSystem::Instance().Exists(
287 executable_module_spec.GetFileSpec())) {
288 module_spec.GetFileSpec() =
289 executable_module_spec.GetFileSpec();
292 if (!module_spec.GetSymbolFileSpec() ||
293 !module_spec.GetSymbolFileSpec()) {
294 Status symbl_error;
295 Symbols::DownloadObjectAndSymbolFile(module_spec, symbl_error,
296 true);
299 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
300 ModuleSP module_sp(new Module(module_spec));
301 if (module_sp.get() && module_sp->GetObjectFile()) {
302 // Get the current target executable
303 ModuleSP exe_module_sp(target.GetExecutableModule());
305 // Make sure you don't already have the right module loaded
306 // and they will be uniqued
307 if (exe_module_sp.get() != module_sp.get())
308 target.SetExecutableModule(module_sp, eLoadDependentsNo);
312 } else if (m_comm.RemoteIsDarwinKernel()) {
313 m_dyld_plugin_name =
314 DynamicLoaderDarwinKernel::GetPluginNameStatic();
315 if (kernel_load_addr != LLDB_INVALID_ADDRESS) {
316 m_kernel_load_addr = kernel_load_addr;
320 // Set the thread ID
321 UpdateThreadListIfNeeded();
322 SetID(1);
323 GetThreadList();
324 SetPrivateState(eStateStopped);
325 StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream());
326 if (async_strm_sp) {
327 const char *cstr;
328 if ((cstr = m_comm.GetKernelVersion()) != NULL) {
329 async_strm_sp->Printf("Version: %s\n", cstr);
330 async_strm_sp->Flush();
332 // if ((cstr = m_comm.GetImagePath ()) != NULL)
333 // {
334 // async_strm_sp->Printf ("Image Path:
335 // %s\n", cstr);
336 // async_strm_sp->Flush();
337 // }
339 } else {
340 error.SetErrorString("KDP_REATTACH failed");
342 } else {
343 error.SetErrorString("KDP_REATTACH failed");
345 } else {
346 error.SetErrorString("invalid reply port from UDP connection");
348 } else {
349 if (error.Success())
350 error.SetErrorStringWithFormat("failed to connect to '%s'",
351 remote_url.str().c_str());
353 if (error.Fail())
354 m_comm.Disconnect();
356 return error;
359 // Process Control
360 Status ProcessKDP::DoLaunch(Module *exe_module,
361 ProcessLaunchInfo &launch_info) {
362 Status error;
363 error.SetErrorString("launching not supported in kdp-remote plug-in");
364 return error;
367 Status
368 ProcessKDP::DoAttachToProcessWithID(lldb::pid_t attach_pid,
369 const ProcessAttachInfo &attach_info) {
370 Status error;
371 error.SetErrorString(
372 "attach to process by ID is not supported in kdp remote debugging");
373 return error;
376 Status
377 ProcessKDP::DoAttachToProcessWithName(const char *process_name,
378 const ProcessAttachInfo &attach_info) {
379 Status error;
380 error.SetErrorString(
381 "attach to process by name is not supported in kdp remote debugging");
382 return error;
385 void ProcessKDP::DidAttach(ArchSpec &process_arch) {
386 Process::DidAttach(process_arch);
388 Log *log = GetLog(KDPLog::Process);
389 LLDB_LOGF(log, "ProcessKDP::DidAttach()");
390 if (GetID() != LLDB_INVALID_PROCESS_ID) {
391 GetHostArchitecture(process_arch);
395 addr_t ProcessKDP::GetImageInfoAddress() { return m_kernel_load_addr; }
397 lldb_private::DynamicLoader *ProcessKDP::GetDynamicLoader() {
398 if (m_dyld_up.get() == NULL)
399 m_dyld_up.reset(DynamicLoader::FindPlugin(this, m_dyld_plugin_name));
400 return m_dyld_up.get();
403 Status ProcessKDP::WillResume() { return Status(); }
405 Status ProcessKDP::DoResume() {
406 Status error;
407 Log *log = GetLog(KDPLog::Process);
408 // Only start the async thread if we try to do any process control
409 if (!m_async_thread.IsJoinable())
410 StartAsyncThread();
412 bool resume = false;
414 // With KDP there is only one thread we can tell what to do
415 ThreadSP kernel_thread_sp(m_thread_list.FindThreadByProtocolID(g_kernel_tid));
417 if (kernel_thread_sp) {
418 const StateType thread_resume_state =
419 kernel_thread_sp->GetTemporaryResumeState();
421 LLDB_LOGF(log, "ProcessKDP::DoResume() thread_resume_state = %s",
422 StateAsCString(thread_resume_state));
423 switch (thread_resume_state) {
424 case eStateSuspended:
425 // Nothing to do here when a thread will stay suspended we just leave the
426 // CPU mask bit set to zero for the thread
427 LLDB_LOGF(log, "ProcessKDP::DoResume() = suspended???");
428 break;
430 case eStateStepping: {
431 lldb::RegisterContextSP reg_ctx_sp(
432 kernel_thread_sp->GetRegisterContext());
434 if (reg_ctx_sp) {
435 LLDB_LOGF(
436 log,
437 "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
438 reg_ctx_sp->HardwareSingleStep(true);
439 resume = true;
440 } else {
441 error.SetErrorStringWithFormat(
442 "KDP thread 0x%llx has no register context",
443 kernel_thread_sp->GetID());
445 } break;
447 case eStateRunning: {
448 lldb::RegisterContextSP reg_ctx_sp(
449 kernel_thread_sp->GetRegisterContext());
451 if (reg_ctx_sp) {
452 LLDB_LOGF(log, "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep "
453 "(false);");
454 reg_ctx_sp->HardwareSingleStep(false);
455 resume = true;
456 } else {
457 error.SetErrorStringWithFormat(
458 "KDP thread 0x%llx has no register context",
459 kernel_thread_sp->GetID());
461 } break;
463 default:
464 // The only valid thread resume states are listed above
465 llvm_unreachable("invalid thread resume state");
469 if (resume) {
470 LLDB_LOGF(log, "ProcessKDP::DoResume () sending resume");
472 if (m_comm.SendRequestResume()) {
473 m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
474 SetPrivateState(eStateRunning);
475 } else
476 error.SetErrorString("KDP resume failed");
477 } else {
478 error.SetErrorString("kernel thread is suspended");
481 return error;
484 lldb::ThreadSP ProcessKDP::GetKernelThread() {
485 // KDP only tells us about one thread/core. Any other threads will usually
486 // be the ones that are read from memory by the OS plug-ins.
488 ThreadSP thread_sp(m_kernel_thread_wp.lock());
489 if (!thread_sp) {
490 thread_sp = std::make_shared<ThreadKDP>(*this, g_kernel_tid);
491 m_kernel_thread_wp = thread_sp;
493 return thread_sp;
496 bool ProcessKDP::DoUpdateThreadList(ThreadList &old_thread_list,
497 ThreadList &new_thread_list) {
498 // locker will keep a mutex locked until it goes out of scope
499 Log *log = GetLog(KDPLog::Thread);
500 LLDB_LOGV(log, "pid = {0}", GetID());
502 // Even though there is a CPU mask, it doesn't mean we can see each CPU
503 // individually, there is really only one. Lets call this thread 1.
504 ThreadSP thread_sp(
505 old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
506 if (!thread_sp)
507 thread_sp = GetKernelThread();
508 new_thread_list.AddThread(thread_sp);
510 return new_thread_list.GetSize(false) > 0;
513 void ProcessKDP::RefreshStateAfterStop() {
514 // Let all threads recover from stopping and do any clean up based on the
515 // previous thread state (if any).
516 m_thread_list.RefreshStateAfterStop();
519 Status ProcessKDP::DoHalt(bool &caused_stop) {
520 Status error;
522 if (m_comm.IsRunning()) {
523 if (m_destroy_in_process) {
524 // If we are attempting to destroy, we need to not return an error to Halt
525 // or DoDestroy won't get called. We are also currently running, so send
526 // a process stopped event
527 SetPrivateState(eStateStopped);
528 } else {
529 error.SetErrorString("KDP cannot interrupt a running kernel");
532 return error;
535 Status ProcessKDP::DoDetach(bool keep_stopped) {
536 Status error;
537 Log *log = GetLog(KDPLog::Process);
538 LLDB_LOGF(log, "ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
540 if (m_comm.IsRunning()) {
541 // We are running and we can't interrupt a running kernel, so we need to
542 // just close the connection to the kernel and hope for the best
543 } else {
544 // If we are going to keep the target stopped, then don't send the
545 // disconnect message.
546 if (!keep_stopped && m_comm.IsConnected()) {
547 const bool success = m_comm.SendRequestDisconnect();
548 if (log) {
549 if (success)
550 log->PutCString(
551 "ProcessKDP::DoDetach() detach packet sent successfully");
552 else
553 log->PutCString(
554 "ProcessKDP::DoDetach() connection channel shutdown failed");
556 m_comm.Disconnect();
559 StopAsyncThread();
560 m_comm.Clear();
562 SetPrivateState(eStateDetached);
563 ResumePrivateStateThread();
565 // KillDebugserverProcess ();
566 return error;
569 Status ProcessKDP::DoDestroy() {
570 // For KDP there really is no difference between destroy and detach
571 bool keep_stopped = false;
572 return DoDetach(keep_stopped);
575 // Process Queries
577 bool ProcessKDP::IsAlive() {
578 return m_comm.IsConnected() && Process::IsAlive();
581 // Process Memory
582 size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size,
583 Status &error) {
584 uint8_t *data_buffer = (uint8_t *)buf;
585 if (m_comm.IsConnected()) {
586 const size_t max_read_size = 512;
587 size_t total_bytes_read = 0;
589 // Read the requested amount of memory in 512 byte chunks
590 while (total_bytes_read < size) {
591 size_t bytes_to_read_this_request = size - total_bytes_read;
592 if (bytes_to_read_this_request > max_read_size) {
593 bytes_to_read_this_request = max_read_size;
595 size_t bytes_read = m_comm.SendRequestReadMemory(
596 addr + total_bytes_read, data_buffer + total_bytes_read,
597 bytes_to_read_this_request, error);
598 total_bytes_read += bytes_read;
599 if (error.Fail() || bytes_read == 0) {
600 return total_bytes_read;
604 return total_bytes_read;
606 error.SetErrorString("not connected");
607 return 0;
610 size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
611 Status &error) {
612 if (m_comm.IsConnected())
613 return m_comm.SendRequestWriteMemory(addr, buf, size, error);
614 error.SetErrorString("not connected");
615 return 0;
618 lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
619 Status &error) {
620 error.SetErrorString(
621 "memory allocation not supported in kdp remote debugging");
622 return LLDB_INVALID_ADDRESS;
625 Status ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) {
626 Status error;
627 error.SetErrorString(
628 "memory deallocation not supported in kdp remote debugging");
629 return error;
632 Status ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) {
633 if (bp_site->HardwareRequired())
634 return Status("Hardware breakpoints are not supported.");
636 if (m_comm.LocalBreakpointsAreSupported()) {
637 Status error;
638 if (!bp_site->IsEnabled()) {
639 if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) {
640 bp_site->SetEnabled(true);
641 bp_site->SetType(BreakpointSite::eExternal);
642 } else {
643 error.SetErrorString("KDP set breakpoint failed");
646 return error;
648 return EnableSoftwareBreakpoint(bp_site);
651 Status ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) {
652 if (m_comm.LocalBreakpointsAreSupported()) {
653 Status error;
654 if (bp_site->IsEnabled()) {
655 BreakpointSite::Type bp_type = bp_site->GetType();
656 if (bp_type == BreakpointSite::eExternal) {
657 if (m_destroy_in_process && m_comm.IsRunning()) {
658 // We are trying to destroy our connection and we are running
659 bp_site->SetEnabled(false);
660 } else {
661 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
662 bp_site->SetEnabled(false);
663 else
664 error.SetErrorString("KDP remove breakpoint failed");
666 } else {
667 error = DisableSoftwareBreakpoint(bp_site);
670 return error;
672 return DisableSoftwareBreakpoint(bp_site);
675 Status ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) {
676 Status error;
677 error.SetErrorString(
678 "watchpoints are not supported in kdp remote debugging");
679 return error;
682 Status ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) {
683 Status error;
684 error.SetErrorString(
685 "watchpoints are not supported in kdp remote debugging");
686 return error;
689 void ProcessKDP::Clear() { m_thread_list.Clear(); }
691 Status ProcessKDP::DoSignal(int signo) {
692 Status error;
693 error.SetErrorString(
694 "sending signals is not supported in kdp remote debugging");
695 return error;
698 void ProcessKDP::Initialize() {
699 static llvm::once_flag g_once_flag;
701 llvm::call_once(g_once_flag, []() {
702 PluginManager::RegisterPlugin(GetPluginNameStatic(),
703 GetPluginDescriptionStatic(), CreateInstance,
704 DebuggerInitialize);
706 ProcessKDPLog::Initialize();
710 void ProcessKDP::DebuggerInitialize(lldb_private::Debugger &debugger) {
711 if (!PluginManager::GetSettingForProcessPlugin(
712 debugger, PluginProperties::GetSettingName())) {
713 const bool is_global_setting = true;
714 PluginManager::CreateSettingForProcessPlugin(
715 debugger, GetGlobalPluginProperties().GetValueProperties(),
716 "Properties for the kdp-remote process plug-in.", is_global_setting);
720 bool ProcessKDP::StartAsyncThread() {
721 Log *log = GetLog(KDPLog::Process);
723 LLDB_LOGF(log, "ProcessKDP::StartAsyncThread ()");
725 if (m_async_thread.IsJoinable())
726 return true;
728 llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
729 "<lldb.process.kdp-remote.async>", [this] { return AsyncThread(); });
730 if (!async_thread) {
731 LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),
732 "failed to launch host thread: {0}");
733 return false;
735 m_async_thread = *async_thread;
736 return m_async_thread.IsJoinable();
739 void ProcessKDP::StopAsyncThread() {
740 Log *log = GetLog(KDPLog::Process);
742 LLDB_LOGF(log, "ProcessKDP::StopAsyncThread ()");
744 m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
746 // Stop the stdio thread
747 if (m_async_thread.IsJoinable())
748 m_async_thread.Join(nullptr);
751 void *ProcessKDP::AsyncThread() {
752 const lldb::pid_t pid = GetID();
754 Log *log = GetLog(KDPLog::Process);
755 LLDB_LOGF(log,
756 "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread starting...",
757 pid);
759 ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
760 EventSP event_sp;
761 const uint32_t desired_event_mask =
762 eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
764 if (listener_sp->StartListeningForEvents(
765 &m_async_broadcaster, desired_event_mask) == desired_event_mask) {
766 bool done = false;
767 while (!done) {
768 LLDB_LOGF(log,
769 "ProcessKDP::AsyncThread (pid = %" PRIu64
770 ") listener.WaitForEvent (NULL, event_sp)...",
771 pid);
772 if (listener_sp->GetEvent(event_sp, std::nullopt)) {
773 uint32_t event_type = event_sp->GetType();
774 LLDB_LOGF(log,
775 "ProcessKDP::AsyncThread (pid = %" PRIu64
776 ") Got an event of type: %d...",
777 pid, event_type);
779 // When we are running, poll for 1 second to try and get an exception
780 // to indicate the process has stopped. If we don't get one, check to
781 // make sure no one asked us to exit
782 bool is_running = false;
783 DataExtractor exc_reply_packet;
784 do {
785 switch (event_type) {
786 case eBroadcastBitAsyncContinue: {
787 is_running = true;
788 if (m_comm.WaitForPacketWithTimeoutMicroSeconds(
789 exc_reply_packet, 1 * USEC_PER_SEC)) {
790 ThreadSP thread_sp(GetKernelThread());
791 if (thread_sp) {
792 lldb::RegisterContextSP reg_ctx_sp(
793 thread_sp->GetRegisterContext());
794 if (reg_ctx_sp)
795 reg_ctx_sp->InvalidateAllRegisters();
796 static_cast<ThreadKDP *>(thread_sp.get())
797 ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet);
800 // TODO: parse the stop reply packet
801 is_running = false;
802 SetPrivateState(eStateStopped);
803 } else {
804 // Check to see if we are supposed to exit. There is no way to
805 // interrupt a running kernel, so all we can do is wait for an
806 // exception or detach...
807 if (listener_sp->GetEvent(event_sp,
808 std::chrono::microseconds(0))) {
809 // We got an event, go through the loop again
810 event_type = event_sp->GetType();
813 } break;
815 case eBroadcastBitAsyncThreadShouldExit:
816 LLDB_LOGF(log,
817 "ProcessKDP::AsyncThread (pid = %" PRIu64
818 ") got eBroadcastBitAsyncThreadShouldExit...",
819 pid);
820 done = true;
821 is_running = false;
822 break;
824 default:
825 LLDB_LOGF(log,
826 "ProcessKDP::AsyncThread (pid = %" PRIu64
827 ") got unknown event 0x%8.8x",
828 pid, event_type);
829 done = true;
830 is_running = false;
831 break;
833 } while (is_running);
834 } else {
835 LLDB_LOGF(log,
836 "ProcessKDP::AsyncThread (pid = %" PRIu64
837 ") listener.WaitForEvent (NULL, event_sp) => false",
838 pid);
839 done = true;
844 LLDB_LOGF(log, "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread exiting...",
845 pid);
847 m_async_thread.Reset();
848 return NULL;
851 class CommandObjectProcessKDPPacketSend : public CommandObjectParsed {
852 private:
853 OptionGroupOptions m_option_group;
854 OptionGroupUInt64 m_command_byte;
855 OptionGroupString m_packet_data;
857 Options *GetOptions() override { return &m_option_group; }
859 public:
860 CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter)
861 : CommandObjectParsed(interpreter, "process plugin packet send",
862 "Send a custom packet through the KDP protocol by "
863 "specifying the command byte and the packet "
864 "payload data. A packet will be sent with a "
865 "correct header and payload, and the raw result "
866 "bytes will be displayed as a string value. ",
867 NULL),
868 m_option_group(),
869 m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone,
870 "Specify the command byte to use when sending the KDP "
871 "request packet.",
873 m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone,
874 "Specify packet payload bytes as a hex ASCII string with "
875 "no spaces or hex prefixes.",
876 NULL) {
877 m_option_group.Append(&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
878 m_option_group.Append(&m_packet_data, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
879 m_option_group.Finalize();
882 ~CommandObjectProcessKDPPacketSend() override = default;
884 void DoExecute(Args &command, CommandReturnObject &result) override {
885 if (!m_command_byte.GetOptionValue().OptionWasSet()) {
886 result.AppendError(
887 "the --command option must be set to a valid command byte");
888 } else {
889 const uint64_t command_byte =
890 m_command_byte.GetOptionValue().GetValueAs<uint64_t>().value_or(0);
891 if (command_byte > 0 && command_byte <= UINT8_MAX) {
892 ProcessKDP *process =
893 (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
894 if (process) {
895 const StateType state = process->GetState();
897 if (StateIsStoppedState(state, true)) {
898 std::vector<uint8_t> payload_bytes;
899 const char *ascii_hex_bytes_cstr =
900 m_packet_data.GetOptionValue().GetCurrentValue();
901 if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) {
902 StringExtractor extractor(ascii_hex_bytes_cstr);
903 const size_t ascii_hex_bytes_cstr_len =
904 extractor.GetStringRef().size();
905 if (ascii_hex_bytes_cstr_len & 1) {
906 result.AppendErrorWithFormat("payload data must contain an "
907 "even number of ASCII hex "
908 "characters: '%s'",
909 ascii_hex_bytes_cstr);
910 return;
912 payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);
913 if (extractor.GetHexBytes(payload_bytes, '\xdd') !=
914 payload_bytes.size()) {
915 result.AppendErrorWithFormat("payload data must only contain "
916 "ASCII hex characters (no "
917 "spaces or hex prefixes): '%s'",
918 ascii_hex_bytes_cstr);
919 return;
922 Status error;
923 DataExtractor reply;
924 process->GetCommunication().SendRawRequest(
925 command_byte,
926 payload_bytes.empty() ? NULL : payload_bytes.data(),
927 payload_bytes.size(), reply, error);
929 if (error.Success()) {
930 // Copy the binary bytes into a hex ASCII string for the result
931 StreamString packet;
932 packet.PutBytesAsRawHex8(
933 reply.GetDataStart(), reply.GetByteSize(),
934 endian::InlHostByteOrder(), endian::InlHostByteOrder());
935 result.AppendMessage(packet.GetString());
936 result.SetStatus(eReturnStatusSuccessFinishResult);
937 return;
938 } else {
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",
944 error.GetError());
945 return;
947 } else {
948 result.AppendErrorWithFormat("process must be stopped in order "
949 "to send KDP packets, state is %s",
950 StateAsCString(state));
952 } else {
953 result.AppendError("invalid process");
955 } else {
956 result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
957 ", valid values are 1 - 255",
958 command_byte);
964 class CommandObjectProcessKDPPacket : public CommandObjectMultiword {
965 private:
966 public:
967 CommandObjectProcessKDPPacket(CommandInterpreter &interpreter)
968 : CommandObjectMultiword(interpreter, "process plugin packet",
969 "Commands that deal with KDP remote packets.",
970 NULL) {
971 LoadSubCommand(
972 "send",
973 CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter)));
976 ~CommandObjectProcessKDPPacket() override = default;
979 class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword {
980 public:
981 CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
982 : CommandObjectMultiword(
983 interpreter, "process plugin",
984 "Commands for operating on a ProcessKDP process.",
985 "process plugin <subcommand> [<subcommand-options>]") {
986 LoadSubCommand("packet", CommandObjectSP(new CommandObjectProcessKDPPacket(
987 interpreter)));
990 ~CommandObjectMultiwordProcessKDP() override = default;
993 CommandObject *ProcessKDP::GetPluginCommandObject() {
994 if (!m_command_sp)
995 m_command_sp = std::make_shared<CommandObjectMultiwordProcessKDP>(
996 GetTarget().GetDebugger().GetCommandInterpreter());
997 return m_command_sp.get();