985 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include <cerrno>10#include <cstdlib>11 12#include <memory>13#include <mutex>14 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/ObjectFile.h"31#include "lldb/Target/RegisterContext.h"32#include "lldb/Target/Target.h"33#include "lldb/Target/Thread.h"34#include "lldb/Utility/LLDBLog.h"35#include "lldb/Utility/Log.h"36#include "lldb/Utility/State.h"37#include "lldb/Utility/StringExtractor.h"38#include "lldb/Utility/UUID.h"39 40#include "llvm/Support/Threading.h"41 42#define USEC_PER_SEC 100000043 44#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"45#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"46#include "ProcessKDP.h"47#include "ProcessKDPLog.h"48#include "ThreadKDP.h"49 50using namespace lldb;51using namespace lldb_private;52 53LLDB_PLUGIN_DEFINE_ADV(ProcessKDP, ProcessMacOSXKernel)54 55namespace {56 57#define LLDB_PROPERTIES_processkdp58#include "ProcessKDPProperties.inc"59 60enum {61#define LLDB_PROPERTIES_processkdp62#include "ProcessKDPPropertiesEnum.inc"63};64 65class PluginProperties : public Properties {66public:67 static llvm::StringRef GetSettingName() {68 return ProcessKDP::GetPluginNameStatic();69 }70 71 PluginProperties() : Properties() {72 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());73 m_collection_sp->Initialize(g_processkdp_properties);74 }75 76 ~PluginProperties() override = default;77 78 uint64_t GetPacketTimeout() {79 const uint32_t idx = ePropertyKDPPacketTimeout;80 return GetPropertyAtIndexAs<uint64_t>(81 idx, g_processkdp_properties[idx].default_uint_value);82 }83};84 85} // namespace86 87static PluginProperties &GetGlobalPluginProperties() {88 static PluginProperties g_settings;89 return g_settings;90}91 92static const lldb::tid_t g_kernel_tid = 1;93 94llvm::StringRef ProcessKDP::GetPluginDescriptionStatic() {95 return "KDP Remote protocol based debugging plug-in for darwin kernel "96 "debugging.";97}98 99void ProcessKDP::Terminate() {100 PluginManager::UnregisterPlugin(ProcessKDP::CreateInstance);101}102 103lldb::ProcessSP ProcessKDP::CreateInstance(TargetSP target_sp,104 ListenerSP listener_sp,105 const FileSpec *crash_file_path,106 bool can_connect) {107 lldb::ProcessSP process_sp;108 if (crash_file_path == NULL)109 process_sp = std::make_shared<ProcessKDP>(target_sp, listener_sp);110 return process_sp;111}112 113bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {114 if (plugin_specified_by_name)115 return true;116 117 // For now we are just making sure the file exists for a given module118 Module *exe_module = target_sp->GetExecutableModulePointer();119 if (exe_module) {120 const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();121 switch (triple_ref.getOS()) {122 case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for123 // iOS, but accept darwin just in case124 case llvm::Triple::MacOSX: // For desktop targets125 case llvm::Triple::IOS: // For arm targets126 case llvm::Triple::TvOS:127 case llvm::Triple::WatchOS:128 case llvm::Triple::XROS: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;134 }135 break;136 137 default:138 break;139 }140 }141 return false;142}143 144// ProcessKDP constructor145ProcessKDP::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));159}160 161// Destructor162ProcessKDP::~ProcessKDP() {163 Clear();164 // We need to call finalize on the process before destroying ourselves to165 // make sure all of the broadcaster cleanup goes as planned. If we destruct166 // this class, then Process::~Process() might have problems trying to fully167 // destroy the broadcaster.168 Finalize(true /* destructing */);169}170 171Status ProcessKDP::DoWillLaunch(Module *module) {172 Status error;173 return Status::FromErrorString(174 "launching not supported in kdp-remote plug-in");175 return error;176}177 178Status ProcessKDP::DoWillAttachToProcessWithID(lldb::pid_t pid) {179 Status error;180 return Status::FromErrorString(181 "attaching to a by process ID not supported in kdp-remote plug-in");182 return error;183}184 185Status ProcessKDP::DoWillAttachToProcessWithName(const char *process_name,186 bool wait_for_launch) {187 Status error;188 return Status::FromErrorString(189 "attaching to a by process name not supported in kdp-remote plug-in");190 return error;191}192 193bool ProcessKDP::GetHostArchitecture(ArchSpec &arch) {194 uint32_t cpu = m_comm.GetCPUType();195 if (cpu) {196 uint32_t sub = m_comm.GetCPUSubtype();197 arch.SetArchitecture(eArchTypeMachO, cpu, sub);198 // Leave architecture vendor as unspecified unknown199 arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);200 arch.GetTriple().setVendorName(llvm::StringRef());201 return true;202 }203 arch.Clear();204 return false;205}206 207Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) {208 Status error;209 210 // Don't let any JIT happen when doing KDP as we can't allocate memory and we211 // don't want to be mucking with threads that might already be handling212 // exceptions213 SetCanJIT(false);214 215 if (remote_url.empty())216 return Status::FromErrorString("empty connection URL");217 218 std::unique_ptr<ConnectionFileDescriptor> conn_up(219 new ConnectionFileDescriptor());220 if (conn_up) {221 // Only try once for now.222 // TODO: check if we should be retrying?223 const uint32_t max_retry_count = 1;224 for (uint32_t retry_count = 0; retry_count < max_retry_count;225 ++retry_count) {226 if (conn_up->Connect(remote_url, &error) == eConnectionStatusSuccess)227 break;228 usleep(100000);229 }230 }231 232 if (conn_up->IsConnected()) {233 const TCPSocket &socket =234 static_cast<const TCPSocket &>(*conn_up->GetReadObject());235 const uint16_t reply_port = socket.GetLocalPortNumber();236 237 if (reply_port != 0) {238 m_comm.SetConnection(std::move(conn_up));239 240 if (m_comm.SendRequestReattach(reply_port)) {241 if (m_comm.SendRequestConnect(reply_port, reply_port,242 "Greetings from LLDB...")) {243 m_comm.GetVersion();244 245 Target &target = GetTarget();246 ArchSpec kernel_arch;247 // The host architecture248 GetHostArchitecture(kernel_arch);249 ArchSpec target_arch = target.GetArchitecture();250 // Merge in any unspecified stuff into the target architecture in251 // case the target arch isn't set at all or incompletely.252 target_arch.MergeFrom(kernel_arch);253 target.SetArchitecture(target_arch);254 255 /* Get the kernel's UUID and load address via KDP_KERNELVERSION256 * packet. */257 /* An EFI kdp session has neither UUID nor load address. */258 259 UUID kernel_uuid = m_comm.GetUUID();260 addr_t kernel_load_addr = m_comm.GetLoadAddress();261 262 if (m_comm.RemoteIsEFI()) {263 // Select an invalid plugin name for the dynamic loader so one264 // doesn't get used since EFI does its own manual loading via265 // python scripting266 m_dyld_plugin_name = "none";267 268 if (kernel_uuid.IsValid()) {269 // If EFI passed in a UUID= try to lookup UUID The slide will not270 // be provided. But the UUID lookup will be used to launch EFI271 // debug scripts from the dSYM, that can load all of the symbols.272 ModuleSpec module_spec;273 module_spec.GetUUID() = kernel_uuid;274 module_spec.GetArchitecture() = target.GetArchitecture();275 276 // Lookup UUID locally, before attempting dsymForUUID like action277 FileSpecList search_paths =278 Target::GetDefaultDebugFileSearchPaths();279 280 StatisticsMap symbol_locator_map;281 module_spec.GetSymbolFileSpec() =282 PluginManager::LocateExecutableSymbolFile(283 module_spec, search_paths, symbol_locator_map);284 if (module_spec.GetSymbolFileSpec()) {285 ModuleSpec executable_module_spec =286 PluginManager::LocateExecutableObjectFile(287 module_spec, symbol_locator_map);288 if (FileSystem::Instance().Exists(289 executable_module_spec.GetFileSpec())) {290 module_spec.GetFileSpec() =291 executable_module_spec.GetFileSpec();292 }293 }294 if (!module_spec.GetSymbolFileSpec() ||295 !module_spec.GetSymbolFileSpec()) {296 Status symbl_error;297 PluginManager::DownloadObjectAndSymbolFile(module_spec,298 symbl_error, true);299 }300 301 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {302 ModuleSP module_sp(new Module(module_spec));303 module_sp->GetSymbolLocatorStatistics().merge(304 symbol_locator_map);305 if (module_sp.get() && module_sp->GetObjectFile()) {306 // Get the current target executable307 ModuleSP exe_module_sp(target.GetExecutableModule());308 309 // Make sure you don't already have the right module loaded310 // and they will be uniqued311 if (exe_module_sp.get() != module_sp.get())312 target.SetExecutableModule(module_sp, eLoadDependentsNo);313 }314 }315 }316 } else if (m_comm.RemoteIsDarwinKernel()) {317 m_dyld_plugin_name =318 DynamicLoaderDarwinKernel::GetPluginNameStatic();319 if (kernel_load_addr != LLDB_INVALID_ADDRESS) {320 m_kernel_load_addr = kernel_load_addr;321 }322 }323 324 // Set the thread ID325 UpdateThreadListIfNeeded();326 SetID(1);327 GetThreadList();328 SetPrivateState(eStateStopped);329 const char *cstr;330 if ((cstr = m_comm.GetKernelVersion()) != NULL)331 target.GetDebugger().GetAsyncOutputStream()->Printf("Version: %s\n",332 cstr);333 } else {334 return Status::FromErrorString("KDP_REATTACH failed");335 }336 } else {337 return Status::FromErrorString("KDP_REATTACH failed");338 }339 } else {340 return Status::FromErrorString("invalid reply port from UDP connection");341 }342 } else {343 if (error.Success())344 error = Status::FromErrorStringWithFormat("failed to connect to '%s'",345 remote_url.str().c_str());346 }347 if (error.Fail())348 m_comm.Disconnect();349 350 return error;351}352 353// Process Control354Status ProcessKDP::DoLaunch(Module *exe_module,355 ProcessLaunchInfo &launch_info) {356 Status error;357 return Status::FromErrorString(358 "launching not supported in kdp-remote plug-in");359 return error;360}361 362Status363ProcessKDP::DoAttachToProcessWithID(lldb::pid_t attach_pid,364 const ProcessAttachInfo &attach_info) {365 Status error;366 return Status::FromErrorString(367 "attach to process by ID is not supported in kdp remote debugging");368 return error;369}370 371Status372ProcessKDP::DoAttachToProcessWithName(const char *process_name,373 const ProcessAttachInfo &attach_info) {374 Status error;375 return Status::FromErrorString(376 "attach to process by name is not supported in kdp remote debugging");377 return error;378}379 380void ProcessKDP::DidAttach(ArchSpec &process_arch) {381 Process::DidAttach(process_arch);382 383 Log *log = GetLog(KDPLog::Process);384 LLDB_LOGF(log, "ProcessKDP::DidAttach()");385 if (GetID() != LLDB_INVALID_PROCESS_ID) {386 GetHostArchitecture(process_arch);387 }388}389 390addr_t ProcessKDP::GetImageInfoAddress() { return m_kernel_load_addr; }391 392lldb_private::DynamicLoader *ProcessKDP::GetDynamicLoader() {393 if (m_dyld_up.get() == NULL)394 m_dyld_up.reset(DynamicLoader::FindPlugin(this, m_dyld_plugin_name));395 return m_dyld_up.get();396}397 398Status ProcessKDP::WillResume() { return Status(); }399 400Status ProcessKDP::DoResume(RunDirection direction) {401 Status error;402 Log *log = GetLog(KDPLog::Process);403 404 if (direction == RunDirection::eRunReverse)405 return Status::FromErrorStringWithFormatv(406 "{0} does not support reverse execution of processes", GetPluginName());407 408 // Only start the async thread if we try to do any process control409 if (!m_async_thread.IsJoinable())410 StartAsyncThread();411 412 bool resume = false;413 414 // With KDP there is only one thread we can tell what to do415 ThreadSP kernel_thread_sp(m_thread_list.FindThreadByProtocolID(g_kernel_tid));416 417 if (kernel_thread_sp) {418 const StateType thread_resume_state =419 kernel_thread_sp->GetTemporaryResumeState();420 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 the426 // CPU mask bit set to zero for the thread427 LLDB_LOGF(log, "ProcessKDP::DoResume() = suspended???");428 break;429 430 case eStateStepping: {431 lldb::RegisterContextSP reg_ctx_sp(432 kernel_thread_sp->GetRegisterContext());433 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 = Status::FromErrorStringWithFormat(442 "KDP thread 0x%llx has no register context",443 kernel_thread_sp->GetID());444 }445 } break;446 447 case eStateRunning: {448 lldb::RegisterContextSP reg_ctx_sp(449 kernel_thread_sp->GetRegisterContext());450 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 = Status::FromErrorStringWithFormat(458 "KDP thread 0x%llx has no register context",459 kernel_thread_sp->GetID());460 }461 } break;462 463 default:464 // The only valid thread resume states are listed above465 llvm_unreachable("invalid thread resume state");466 }467 }468 469 if (resume) {470 LLDB_LOGF(log, "ProcessKDP::DoResume () sending resume");471 472 if (m_comm.SendRequestResume()) {473 m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);474 SetPrivateState(eStateRunning);475 } else476 return Status::FromErrorString("KDP resume failed");477 } else {478 return Status::FromErrorString("kernel thread is suspended");479 }480 481 return error;482}483 484lldb::ThreadSP ProcessKDP::GetKernelThread() {485 // KDP only tells us about one thread/core. Any other threads will usually486 // be the ones that are read from memory by the OS plug-ins.487 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;492 }493 return thread_sp;494}495 496bool ProcessKDP::DoUpdateThreadList(ThreadList &old_thread_list,497 ThreadList &new_thread_list) {498 // locker will keep a mutex locked until it goes out of scope499 Log *log = GetLog(KDPLog::Thread);500 LLDB_LOGV(log, "pid = {0}", GetID());501 502 // Even though there is a CPU mask, it doesn't mean we can see each CPU503 // 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);509 510 return new_thread_list.GetSize(false) > 0;511}512 513void ProcessKDP::RefreshStateAfterStop() {514 // Let all threads recover from stopping and do any clean up based on the515 // previous thread state (if any).516 m_thread_list.RefreshStateAfterStop();517}518 519Status ProcessKDP::DoHalt(bool &caused_stop) {520 Status error;521 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 Halt525 // or DoDestroy won't get called. We are also currently running, so send526 // a process stopped event527 SetPrivateState(eStateStopped);528 } else {529 return Status::FromErrorString("KDP cannot interrupt a running kernel");530 }531 }532 return error;533}534 535Status 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);539 540 if (m_comm.IsRunning()) {541 // We are running and we can't interrupt a running kernel, so we need to542 // just close the connection to the kernel and hope for the best543 } else {544 // If we are going to keep the target stopped, then don't send the545 // 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 else553 log->PutCString(554 "ProcessKDP::DoDetach() connection channel shutdown failed");555 }556 m_comm.Disconnect();557 }558 }559 StopAsyncThread();560 m_comm.Clear();561 562 SetPrivateState(eStateDetached);563 ResumePrivateStateThread();564 565 // KillDebugserverProcess ();566 return error;567}568 569Status ProcessKDP::DoDestroy() {570 // For KDP there really is no difference between destroy and detach571 bool keep_stopped = false;572 return DoDetach(keep_stopped);573}574 575// Process Queries576 577bool ProcessKDP::IsAlive() {578 return m_comm.IsConnected() && Process::IsAlive();579}580 581// Process Memory582size_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;588 589 // Read the requested amount of memory in 512 byte chunks590 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;594 }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;601 }602 }603 604 return total_bytes_read;605 }606 error = Status::FromErrorString("not connected");607 return 0;608}609 610size_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 = Status::FromErrorString("not connected");615 return 0;616}617 618lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,619 Status &error) {620 error = Status::FromErrorString(621 "memory allocation not supported in kdp remote debugging");622 return LLDB_INVALID_ADDRESS;623}624 625Status ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) {626 Status error;627 return Status::FromErrorString(628 "memory deallocation not supported in kdp remote debugging");629 return error;630}631 632Status ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) {633 if (bp_site->HardwareRequired())634 return Status::FromErrorString("Hardware breakpoints are not supported.");635 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 return Status::FromErrorString("KDP set breakpoint failed");644 }645 }646 return error;647 }648 return EnableSoftwareBreakpoint(bp_site);649}650 651Status 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 running659 bp_site->SetEnabled(false);660 } else {661 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))662 bp_site->SetEnabled(false);663 else664 return Status::FromErrorString("KDP remove breakpoint failed");665 }666 } else {667 error = DisableSoftwareBreakpoint(bp_site);668 }669 }670 return error;671 }672 return DisableSoftwareBreakpoint(bp_site);673}674 675void ProcessKDP::Clear() { m_thread_list.Clear(); }676 677Status ProcessKDP::DoSignal(int signo) {678 Status error;679 return Status::FromErrorString(680 "sending signals is not supported in kdp remote debugging");681 return error;682}683 684void ProcessKDP::Initialize() {685 static llvm::once_flag g_once_flag;686 687 llvm::call_once(g_once_flag, []() {688 PluginManager::RegisterPlugin(GetPluginNameStatic(),689 GetPluginDescriptionStatic(), CreateInstance,690 DebuggerInitialize);691 692 ProcessKDPLog::Initialize();693 });694}695 696void ProcessKDP::DebuggerInitialize(lldb_private::Debugger &debugger) {697 if (!PluginManager::GetSettingForProcessPlugin(698 debugger, PluginProperties::GetSettingName())) {699 const bool is_global_setting = true;700 PluginManager::CreateSettingForProcessPlugin(701 debugger, GetGlobalPluginProperties().GetValueProperties(),702 "Properties for the kdp-remote process plug-in.", is_global_setting);703 }704}705 706bool ProcessKDP::StartAsyncThread() {707 Log *log = GetLog(KDPLog::Process);708 709 LLDB_LOGF(log, "ProcessKDP::StartAsyncThread ()");710 711 if (m_async_thread.IsJoinable())712 return true;713 714 llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(715 "<lldb.process.kdp-remote.async>", [this] { return AsyncThread(); });716 if (!async_thread) {717 LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(),718 "failed to launch host thread: {0}");719 return false;720 }721 m_async_thread = *async_thread;722 return m_async_thread.IsJoinable();723}724 725void ProcessKDP::StopAsyncThread() {726 Log *log = GetLog(KDPLog::Process);727 728 LLDB_LOGF(log, "ProcessKDP::StopAsyncThread ()");729 730 m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);731 732 // Stop the stdio thread733 if (m_async_thread.IsJoinable())734 m_async_thread.Join(nullptr);735}736 737void *ProcessKDP::AsyncThread() {738 const lldb::pid_t pid = GetID();739 740 Log *log = GetLog(KDPLog::Process);741 LLDB_LOGF(log,742 "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread starting...",743 pid);744 745 ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));746 EventSP event_sp;747 const uint32_t desired_event_mask =748 eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;749 750 if (listener_sp->StartListeningForEvents(751 &m_async_broadcaster, desired_event_mask) == desired_event_mask) {752 bool done = false;753 while (!done) {754 LLDB_LOGF(log,755 "ProcessKDP::AsyncThread (pid = %" PRIu64756 ") listener.WaitForEvent (NULL, event_sp)...",757 pid);758 if (listener_sp->GetEvent(event_sp, std::nullopt)) {759 uint32_t event_type = event_sp->GetType();760 LLDB_LOGF(log,761 "ProcessKDP::AsyncThread (pid = %" PRIu64762 ") Got an event of type: %d...",763 pid, event_type);764 765 // When we are running, poll for 1 second to try and get an exception766 // to indicate the process has stopped. If we don't get one, check to767 // make sure no one asked us to exit768 bool is_running = false;769 DataExtractor exc_reply_packet;770 do {771 switch (event_type) {772 case eBroadcastBitAsyncContinue: {773 is_running = true;774 if (m_comm.WaitForPacketWithTimeoutMicroSeconds(775 exc_reply_packet, 1 * USEC_PER_SEC)) {776 ThreadSP thread_sp(GetKernelThread());777 if (thread_sp) {778 lldb::RegisterContextSP reg_ctx_sp(779 thread_sp->GetRegisterContext());780 if (reg_ctx_sp)781 reg_ctx_sp->InvalidateAllRegisters();782 static_cast<ThreadKDP *>(thread_sp.get())783 ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet);784 }785 786 // TODO: parse the stop reply packet787 is_running = false;788 SetPrivateState(eStateStopped);789 } else {790 // Check to see if we are supposed to exit. There is no way to791 // interrupt a running kernel, so all we can do is wait for an792 // exception or detach...793 if (listener_sp->GetEvent(event_sp,794 std::chrono::microseconds(0))) {795 // We got an event, go through the loop again796 event_type = event_sp->GetType();797 }798 }799 } break;800 801 case eBroadcastBitAsyncThreadShouldExit:802 LLDB_LOGF(log,803 "ProcessKDP::AsyncThread (pid = %" PRIu64804 ") got eBroadcastBitAsyncThreadShouldExit...",805 pid);806 done = true;807 is_running = false;808 break;809 810 default:811 LLDB_LOGF(log,812 "ProcessKDP::AsyncThread (pid = %" PRIu64813 ") got unknown event 0x%8.8x",814 pid, event_type);815 done = true;816 is_running = false;817 break;818 }819 } while (is_running);820 } else {821 LLDB_LOGF(log,822 "ProcessKDP::AsyncThread (pid = %" PRIu64823 ") listener.WaitForEvent (NULL, event_sp) => false",824 pid);825 done = true;826 }827 }828 }829 830 LLDB_LOGF(log, "ProcessKDP::AsyncThread(pid = %" PRIu64 ") thread exiting...",831 pid);832 833 m_async_thread.Reset();834 return NULL;835}836 837class CommandObjectProcessKDPPacketSend : public CommandObjectParsed {838private:839 OptionGroupOptions m_option_group;840 OptionGroupUInt64 m_command_byte;841 OptionGroupString m_packet_data;842 843 Options *GetOptions() override { return &m_option_group; }844 845public:846 CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter)847 : CommandObjectParsed(interpreter, "process plugin packet send",848 "Send a custom packet through the KDP protocol by "849 "specifying the command byte and the packet "850 "payload data. A packet will be sent with a "851 "correct header and payload, and the raw result "852 "bytes will be displayed as a string value. ",853 NULL),854 m_option_group(),855 m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone,856 "Specify the command byte to use when sending the KDP "857 "request packet.",858 0),859 m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone,860 "Specify packet payload bytes as a hex ASCII string with "861 "no spaces or hex prefixes.",862 NULL) {863 m_option_group.Append(&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);864 m_option_group.Append(&m_packet_data, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);865 m_option_group.Finalize();866 }867 868 ~CommandObjectProcessKDPPacketSend() override = default;869 870 void DoExecute(Args &command, CommandReturnObject &result) override {871 if (!m_command_byte.GetOptionValue().OptionWasSet()) {872 result.AppendError(873 "the --command option must be set to a valid command byte");874 } else {875 const uint64_t command_byte =876 m_command_byte.GetOptionValue().GetValueAs<uint64_t>().value_or(0);877 if (command_byte > 0 && command_byte <= UINT8_MAX) {878 ProcessKDP *process =879 (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();880 if (process) {881 const StateType state = process->GetState();882 883 if (StateIsStoppedState(state, true)) {884 std::vector<uint8_t> payload_bytes;885 const char *ascii_hex_bytes_cstr =886 m_packet_data.GetOptionValue().GetCurrentValue();887 if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) {888 StringExtractor extractor(ascii_hex_bytes_cstr);889 const size_t ascii_hex_bytes_cstr_len =890 extractor.GetStringRef().size();891 if (ascii_hex_bytes_cstr_len & 1) {892 result.AppendErrorWithFormat("payload data must contain an "893 "even number of ASCII hex "894 "characters: '%s'",895 ascii_hex_bytes_cstr);896 return;897 }898 payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);899 if (extractor.GetHexBytes(payload_bytes, '\xdd') !=900 payload_bytes.size()) {901 result.AppendErrorWithFormat("payload data must only contain "902 "ASCII hex characters (no "903 "spaces or hex prefixes): '%s'",904 ascii_hex_bytes_cstr);905 return;906 }907 }908 Status error;909 DataExtractor reply;910 process->GetCommunication().SendRawRequest(911 command_byte,912 payload_bytes.empty() ? NULL : payload_bytes.data(),913 payload_bytes.size(), reply, error);914 915 if (error.Success()) {916 // Copy the binary bytes into a hex ASCII string for the result917 StreamString packet;918 packet.PutBytesAsRawHex8(919 reply.GetDataStart(), reply.GetByteSize(),920 endian::InlHostByteOrder(), endian::InlHostByteOrder());921 result.AppendMessage(packet.GetString());922 result.SetStatus(eReturnStatusSuccessFinishResult);923 return;924 } else {925 const char *error_cstr = error.AsCString();926 if (error_cstr && error_cstr[0])927 result.AppendError(error_cstr);928 else929 result.AppendErrorWithFormat("unknown error 0x%8.8x",930 error.GetError());931 return;932 }933 } else {934 result.AppendErrorWithFormat("process must be stopped in order "935 "to send KDP packets, state is %s",936 StateAsCString(state));937 }938 } else {939 result.AppendError("invalid process");940 }941 } else {942 result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64943 ", valid values are 1 - 255",944 command_byte);945 }946 }947 }948};949 950class CommandObjectProcessKDPPacket : public CommandObjectMultiword {951private:952public:953 CommandObjectProcessKDPPacket(CommandInterpreter &interpreter)954 : CommandObjectMultiword(interpreter, "process plugin packet",955 "Commands that deal with KDP remote packets.",956 NULL) {957 LoadSubCommand(958 "send",959 CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter)));960 }961 962 ~CommandObjectProcessKDPPacket() override = default;963};964 965class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword {966public:967 CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)968 : CommandObjectMultiword(969 interpreter, "process plugin",970 "Commands for operating on a ProcessKDP process.",971 "process plugin <subcommand> [<subcommand-options>]") {972 LoadSubCommand("packet", CommandObjectSP(new CommandObjectProcessKDPPacket(973 interpreter)));974 }975 976 ~CommandObjectMultiwordProcessKDP() override = default;977};978 979CommandObject *ProcessKDP::GetPluginCommandObject() {980 if (!m_command_sp)981 m_command_sp = std::make_shared<CommandObjectMultiwordProcessKDP>(982 GetTarget().GetDebugger().GetCommandInterpreter());983 return m_command_sp.get();984}985