blob: 5542018a4f90e78eecf7ed3424f7c241d4e08781 [file] [log] [blame]
Greg Clayton59ec5122011-07-15 18:02:58 +00001//===-- ProcessKDP.cpp ------------------------------------------*- C++ -*-===//
Greg Claytonf9765ac2011-07-15 03:27:12 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Greg Claytonf9765ac2011-07-15 03:27:12 +00006//
7//===----------------------------------------------------------------------===//
8
Greg Claytonf9765ac2011-07-15 03:27:12 +00009#include <errno.h>
10#include <stdlib.h>
11
Jonas Devlieghere796ac802019-02-11 23:13:08 +000012#include <memory>
Benjamin Kramer3f69fa62015-04-03 10:55:00 +000013#include <mutex>
14
Greg Clayton07e66e32011-07-20 03:41:06 +000015#include "lldb/Core/Debugger.h"
Greg Clayton1f746072012-08-29 21:13:06 +000016#include "lldb/Core/Module.h"
Jason Molenda4bd4e7e2012-09-29 04:02:01 +000017#include "lldb/Core/ModuleSpec.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000018#include "lldb/Core/PluginManager.h"
Zachary Turner93a66fc2014-10-06 21:22:36 +000019#include "lldb/Host/ConnectionFileDescriptor.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000020#include "lldb/Host/Host.h"
Zachary Turner39de3112014-09-09 20:54:56 +000021#include "lldb/Host/ThreadLauncher.h"
Oleksiy Vyalove98628c2015-10-15 23:54:09 +000022#include "lldb/Host/common/TCPSocket.h"
Greg Clayton1d19a2f2012-10-19 22:22:57 +000023#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"
Ilia K41204d02015-03-04 12:05:24 +000029#include "lldb/Interpreter/OptionValueProperties.h"
Zachary Turner80552912019-02-27 21:42:10 +000030#include "lldb/Symbol/LocateSymbolFile.h"
Greg Clayton1f746072012-08-29 21:13:06 +000031#include "lldb/Symbol/ObjectFile.h"
Greg Clayton7925fbb2012-09-21 16:31:20 +000032#include "lldb/Target/RegisterContext.h"
Greg Clayton57508022011-07-15 16:31:38 +000033#include "lldb/Target/Target.h"
Greg Claytona63d08c2011-07-19 03:57:15 +000034#include "lldb/Target/Thread.h"
Jonas Devliegheref39c2e12019-07-05 17:42:08 +000035#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000036#include "lldb/Utility/State.h"
Bruce Mitchener45788152015-07-07 23:59:01 +000037#include "lldb/Utility/StringExtractor.h"
Pavel Labathd821c992018-08-07 11:07:21 +000038#include "lldb/Utility/UUID.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000039
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000040#include "llvm/Support/Threading.h"
41
Charles Davis510938e2013-08-27 05:04:57 +000042#define USEC_PER_SEC 1000000
43
Kate Stoneb9c1b512016-09-06 20:57:50 +000044#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
45#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000046#include "ProcessKDP.h"
47#include "ProcessKDPLog.h"
Greg Claytona63d08c2011-07-19 03:57:15 +000048#include "ThreadKDP.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000049
50using namespace lldb;
51using namespace lldb_private;
52
Greg Clayton7f982402013-07-15 22:54:20 +000053namespace {
54
Tatyana Krasnukhae40db052018-09-27 07:11:58 +000055static constexpr PropertyDefinition g_properties[] = {
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000056#define LLDB_PROPERTIES_processkdp
57#include "Properties.inc"
58};
Greg Clayton7f982402013-07-15 22:54:20 +000059
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000060enum {
61#define LLDB_PROPERTIES_processkdp
62#include "PropertiesEnum.inc"
63};
Greg Clayton7f982402013-07-15 22:54:20 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065class PluginProperties : public Properties {
66public:
67 static ConstString GetSettingName() {
68 return ProcessKDP::GetPluginNameStatic();
69 }
Greg Clayton7f982402013-07-15 22:54:20 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 PluginProperties() : Properties() {
Jonas Devlieghere796ac802019-02-11 23:13:08 +000072 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
Kate Stoneb9c1b512016-09-06 20:57:50 +000073 m_collection_sp->Initialize(g_properties);
74 }
Greg Clayton7f982402013-07-15 22:54:20 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076 virtual ~PluginProperties() {}
77
78 uint64_t GetPacketTimeout() {
Jonas Devlieghere971f9ca2019-07-25 21:36:37 +000079 const uint32_t idx = ePropertyKDPPacketTimeout;
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 return m_collection_sp->GetPropertyAtIndexAsUInt64(
81 NULL, idx, g_properties[idx].default_uint_value);
82 }
83};
84
85typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
86
87static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
88 static ProcessKDPPropertiesSP g_settings_sp;
89 if (!g_settings_sp)
Jonas Devlieghere796ac802019-02-11 23:13:08 +000090 g_settings_sp = std::make_shared<PluginProperties>();
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 return g_settings_sp;
92}
93
Greg Clayton7f982402013-07-15 22:54:20 +000094} // anonymous namespace end
95
Andrew Kaylorba4e61d2013-05-07 18:35:34 +000096static const lldb::tid_t g_kernel_tid = 1;
97
Kate Stoneb9c1b512016-09-06 20:57:50 +000098ConstString ProcessKDP::GetPluginNameStatic() {
99 static ConstString g_name("kdp-remote");
100 return g_name;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000101}
102
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103const char *ProcessKDP::GetPluginDescriptionStatic() {
104 return "KDP Remote protocol based debugging plug-in for darwin kernel "
105 "debugging.";
Greg Claytonf9765ac2011-07-15 03:27:12 +0000106}
107
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108void ProcessKDP::Terminate() {
109 PluginManager::UnregisterPlugin(ProcessKDP::CreateInstance);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000110}
111
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112lldb::ProcessSP ProcessKDP::CreateInstance(TargetSP target_sp,
113 ListenerSP listener_sp,
114 const FileSpec *crash_file_path) {
115 lldb::ProcessSP process_sp;
116 if (crash_file_path == NULL)
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000117 process_sp = std::make_shared<ProcessKDP>(target_sp, listener_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118 return process_sp;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000119}
120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
122 if (plugin_specified_by_name)
123 return true;
Greg Clayton596ed242011-10-21 21:41:45 +0000124
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 // For now we are just making sure the file exists for a given module
126 Module *exe_module = target_sp->GetExecutableModulePointer();
127 if (exe_module) {
128 const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
129 switch (triple_ref.getOS()) {
130 case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for
131 // iOS, but accept darwin just in case
132 case llvm::Triple::MacOSX: // For desktop targets
133 case llvm::Triple::IOS: // For arm targets
134 case llvm::Triple::TvOS:
135 case llvm::Triple::WatchOS:
136 if (triple_ref.getVendor() == llvm::Triple::Apple) {
137 ObjectFile *exe_objfile = exe_module->GetObjectFile();
138 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
139 exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
140 return true;
141 }
142 break;
Greg Clayton70512312012-05-08 01:45:38 +0000143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 default:
145 break;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000146 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 }
148 return false;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000149}
150
Greg Claytonf9765ac2011-07-15 03:27:12 +0000151// ProcessKDP constructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp)
153 : Process(target_sp, listener_sp),
154 m_comm("lldb.process.kdp-remote.communication"),
155 m_async_broadcaster(NULL, "lldb.process.kdp-remote.async-broadcaster"),
156 m_dyld_plugin_name(), m_kernel_load_addr(LLDB_INVALID_ADDRESS),
157 m_command_sp(), m_kernel_thread_wp() {
158 m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
159 "async thread should exit");
160 m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
161 "async thread continue");
162 const uint64_t timeout_seconds =
163 GetGlobalPluginProperties()->GetPacketTimeout();
164 if (timeout_seconds > 0)
Pavel Labath5cddd602016-11-02 10:13:54 +0000165 m_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
Greg Claytonf9765ac2011-07-15 03:27:12 +0000166}
167
Greg Claytonf9765ac2011-07-15 03:27:12 +0000168// Destructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169ProcessKDP::~ProcessKDP() {
170 Clear();
Adrian Prantl05097242018-04-30 16:49:04 +0000171 // We need to call finalize on the process before destroying ourselves to
172 // make sure all of the broadcaster cleanup goes as planned. If we destruct
173 // this class, then Process::~Process() might have problems trying to fully
174 // destroy the broadcaster.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175 Finalize();
Greg Claytonf9765ac2011-07-15 03:27:12 +0000176}
177
Greg Claytonf9765ac2011-07-15 03:27:12 +0000178// PluginInterface
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179lldb_private::ConstString ProcessKDP::GetPluginName() {
180 return GetPluginNameStatic();
Greg Claytonf9765ac2011-07-15 03:27:12 +0000181}
182
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183uint32_t ProcessKDP::GetPluginVersion() { return 1; }
184
Zachary Turner97206d52017-05-12 04:51:55 +0000185Status ProcessKDP::WillLaunch(Module *module) {
186 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000187 error.SetErrorString("launching not supported in kdp-remote plug-in");
188 return error;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000189}
190
Zachary Turner97206d52017-05-12 04:51:55 +0000191Status ProcessKDP::WillAttachToProcessWithID(lldb::pid_t pid) {
192 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 error.SetErrorString(
194 "attaching to a by process ID not supported in kdp-remote plug-in");
195 return error;
196}
197
Zachary Turner97206d52017-05-12 04:51:55 +0000198Status ProcessKDP::WillAttachToProcessWithName(const char *process_name,
199 bool wait_for_launch) {
200 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201 error.SetErrorString(
202 "attaching to a by process name not supported in kdp-remote plug-in");
203 return error;
204}
205
206bool ProcessKDP::GetHostArchitecture(ArchSpec &arch) {
207 uint32_t cpu = m_comm.GetCPUType();
208 if (cpu) {
209 uint32_t sub = m_comm.GetCPUSubtype();
210 arch.SetArchitecture(eArchTypeMachO, cpu, sub);
211 // Leave architecture vendor as unspecified unknown
212 arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);
213 arch.GetTriple().setVendorName(llvm::StringRef());
214 return true;
215 }
216 arch.Clear();
217 return false;
218}
219
Zachary Turner97206d52017-05-12 04:51:55 +0000220Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
221 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222
Adrian Prantl05097242018-04-30 16:49:04 +0000223 // Don't let any JIT happen when doing KDP as we can't allocate memory and we
224 // don't want to be mucking with threads that might already be handling
225 // exceptions
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226 SetCanJIT(false);
227
Greg Clayton3ce7e992016-12-07 23:51:49 +0000228 if (remote_url.empty()) {
229 error.SetErrorStringWithFormat("empty connection URL");
Greg Claytonf9765ac2011-07-15 03:27:12 +0000230 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231 }
Greg Claytonf9765ac2011-07-15 03:27:12 +0000232
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000233 std::unique_ptr<ConnectionFileDescriptor> conn_up(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234 new ConnectionFileDescriptor());
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000235 if (conn_up) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000236 // Only try once for now.
237 // TODO: check if we should be retrying?
238 const uint32_t max_retry_count = 1;
239 for (uint32_t retry_count = 0; retry_count < max_retry_count;
240 ++retry_count) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000241 if (conn_up->Connect(remote_url, &error) == eConnectionStatusSuccess)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242 break;
243 usleep(100000);
Greg Claytona3706882015-10-28 23:26:59 +0000244 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000245 }
Greg Claytona3706882015-10-28 23:26:59 +0000246
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000247 if (conn_up->IsConnected()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248 const TCPSocket &socket =
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000249 static_cast<const TCPSocket &>(*conn_up->GetReadObject());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250 const uint16_t reply_port = socket.GetLocalPortNumber();
Greg Clayton7925fbb2012-09-21 16:31:20 +0000251
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252 if (reply_port != 0) {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000253 m_comm.SetConnection(conn_up.release());
Greg Clayton7925fbb2012-09-21 16:31:20 +0000254
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255 if (m_comm.SendRequestReattach(reply_port)) {
256 if (m_comm.SendRequestConnect(reply_port, reply_port,
257 "Greetings from LLDB...")) {
258 m_comm.GetVersion();
Greg Clayton3a29bdb2011-07-17 20:36:25 +0000259
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260 Target &target = GetTarget();
261 ArchSpec kernel_arch;
262 // The host architecture
263 GetHostArchitecture(kernel_arch);
264 ArchSpec target_arch = target.GetArchitecture();
265 // Merge in any unspecified stuff into the target architecture in
266 // case the target arch isn't set at all or incompletely.
267 target_arch.MergeFrom(kernel_arch);
268 target.SetArchitecture(target_arch);
Greg Clayton3a29bdb2011-07-17 20:36:25 +0000269
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270 /* Get the kernel's UUID and load address via KDP_KERNELVERSION
271 * packet. */
272 /* An EFI kdp session has neither UUID nor load address. */
Greg Clayton3a29bdb2011-07-17 20:36:25 +0000273
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274 UUID kernel_uuid = m_comm.GetUUID();
275 addr_t kernel_load_addr = m_comm.GetLoadAddress();
Greg Clayton3a29bdb2011-07-17 20:36:25 +0000276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277 if (m_comm.RemoteIsEFI()) {
278 // Select an invalid plugin name for the dynamic loader so one
Adrian Prantl05097242018-04-30 16:49:04 +0000279 // doesn't get used since EFI does its own manual loading via
280 // python scripting
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281 static ConstString g_none_dynamic_loader("none");
282 m_dyld_plugin_name = g_none_dynamic_loader;
Greg Claytona3706882015-10-28 23:26:59 +0000283
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 if (kernel_uuid.IsValid()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000285 // If EFI passed in a UUID= try to lookup UUID The slide will not
286 // be provided. But the UUID lookup will be used to launch EFI
287 // debug scripts from the dSYM, that can load all of the symbols.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000288 ModuleSpec module_spec;
289 module_spec.GetUUID() = kernel_uuid;
290 module_spec.GetArchitecture() = target.GetArchitecture();
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000291
Kate Stoneb9c1b512016-09-06 20:57:50 +0000292 // Lookup UUID locally, before attempting dsymForUUID like action
Zachary Turnera313ec12019-03-06 18:44:27 +0000293 FileSpecList search_paths =
294 Target::GetDefaultDebugFileSearchPaths();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 module_spec.GetSymbolFileSpec() =
Zachary Turnera313ec12019-03-06 18:44:27 +0000296 Symbols::LocateExecutableSymbolFile(module_spec,
297 search_paths);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298 if (module_spec.GetSymbolFileSpec()) {
299 ModuleSpec executable_module_spec =
300 Symbols::LocateExecutableObjectFile(module_spec);
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000301 if (FileSystem::Instance().Exists(
302 executable_module_spec.GetFileSpec())) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303 module_spec.GetFileSpec() =
304 executable_module_spec.GetFileSpec();
Greg Clayton3a29bdb2011-07-17 20:36:25 +0000305 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000306 }
307 if (!module_spec.GetSymbolFileSpec() ||
308 !module_spec.GetSymbolFileSpec())
309 Symbols::DownloadObjectAndSymbolFile(module_spec, true);
Greg Clayton3a29bdb2011-07-17 20:36:25 +0000310
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000311 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000312 ModuleSP module_sp(new Module(module_spec));
313 if (module_sp.get() && module_sp->GetObjectFile()) {
314 // Get the current target executable
315 ModuleSP exe_module_sp(target.GetExecutableModule());
316
317 // Make sure you don't already have the right module loaded
318 // and they will be uniqued
319 if (exe_module_sp.get() != module_sp.get())
Jonas Devliegheref9a07e92018-09-20 09:09:05 +0000320 target.SetExecutableModule(module_sp, eLoadDependentsNo);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000321 }
322 }
323 }
324 } else if (m_comm.RemoteIsDarwinKernel()) {
325 m_dyld_plugin_name =
326 DynamicLoaderDarwinKernel::GetPluginNameStatic();
327 if (kernel_load_addr != LLDB_INVALID_ADDRESS) {
328 m_kernel_load_addr = kernel_load_addr;
329 }
330 }
331
332 // Set the thread ID
333 UpdateThreadListIfNeeded();
334 SetID(1);
335 GetThreadList();
336 SetPrivateState(eStateStopped);
337 StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream());
338 if (async_strm_sp) {
339 const char *cstr;
340 if ((cstr = m_comm.GetKernelVersion()) != NULL) {
341 async_strm_sp->Printf("Version: %s\n", cstr);
342 async_strm_sp->Flush();
343 }
344 // if ((cstr = m_comm.GetImagePath ()) != NULL)
345 // {
346 // async_strm_sp->Printf ("Image Path:
347 // %s\n", cstr);
348 // async_strm_sp->Flush();
349 // }
350 }
351 } else {
352 error.SetErrorString("KDP_REATTACH failed");
353 }
354 } else {
355 error.SetErrorString("KDP_REATTACH failed");
356 }
357 } else {
358 error.SetErrorString("invalid reply port from UDP connection");
359 }
360 } else {
361 if (error.Success())
Greg Clayton3ce7e992016-12-07 23:51:49 +0000362 error.SetErrorStringWithFormat("failed to connect to '%s'",
363 remote_url.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000364 }
365 if (error.Fail())
366 m_comm.Disconnect();
367
368 return error;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000369}
370
Greg Claytonf9765ac2011-07-15 03:27:12 +0000371// Process Control
Zachary Turner97206d52017-05-12 04:51:55 +0000372Status ProcessKDP::DoLaunch(Module *exe_module,
373 ProcessLaunchInfo &launch_info) {
374 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000375 error.SetErrorString("launching not supported in kdp-remote plug-in");
376 return error;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000377}
378
Zachary Turner97206d52017-05-12 04:51:55 +0000379Status
380ProcessKDP::DoAttachToProcessWithID(lldb::pid_t attach_pid,
381 const ProcessAttachInfo &attach_info) {
382 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000384 "attach to process by ID is not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000385 return error;
Han Ming Ong84647042012-02-25 01:07:38 +0000386}
387
Zachary Turner97206d52017-05-12 04:51:55 +0000388Status
389ProcessKDP::DoAttachToProcessWithName(const char *process_name,
390 const ProcessAttachInfo &attach_info) {
391 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000392 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000393 "attach to process by name is not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394 return error;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000395}
396
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397void ProcessKDP::DidAttach(ArchSpec &process_arch) {
398 Process::DidAttach(process_arch);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000399
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000401 LLDB_LOGF(log, "ProcessKDP::DidAttach()");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000402 if (GetID() != LLDB_INVALID_PROCESS_ID) {
403 GetHostArchitecture(process_arch);
404 }
405}
406
407addr_t ProcessKDP::GetImageInfoAddress() { return m_kernel_load_addr; }
408
409lldb_private::DynamicLoader *ProcessKDP::GetDynamicLoader() {
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000410 if (m_dyld_up.get() == NULL)
411 m_dyld_up.reset(DynamicLoader::FindPlugin(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000412 this,
413 m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000414 return m_dyld_up.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415}
416
Zachary Turner97206d52017-05-12 04:51:55 +0000417Status ProcessKDP::WillResume() { return Status(); }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000418
Zachary Turner97206d52017-05-12 04:51:55 +0000419Status ProcessKDP::DoResume() {
420 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
422 // Only start the async thread if we try to do any process control
423 if (!m_async_thread.IsJoinable())
424 StartAsyncThread();
425
426 bool resume = false;
427
428 // With KDP there is only one thread we can tell what to do
429 ThreadSP kernel_thread_sp(m_thread_list.FindThreadByProtocolID(g_kernel_tid));
430
431 if (kernel_thread_sp) {
432 const StateType thread_resume_state =
433 kernel_thread_sp->GetTemporaryResumeState();
434
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000435 LLDB_LOGF(log, "ProcessKDP::DoResume() thread_resume_state = %s",
436 StateAsCString(thread_resume_state));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000437 switch (thread_resume_state) {
438 case eStateSuspended:
Adrian Prantl05097242018-04-30 16:49:04 +0000439 // Nothing to do here when a thread will stay suspended we just leave the
440 // CPU mask bit set to zero for the thread
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000441 LLDB_LOGF(log, "ProcessKDP::DoResume() = suspended???");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 break;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444 case eStateStepping: {
445 lldb::RegisterContextSP reg_ctx_sp(
446 kernel_thread_sp->GetRegisterContext());
Jason Molenda5e8534e2012-10-03 01:29:34 +0000447
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448 if (reg_ctx_sp) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000449 LLDB_LOGF(
450 log,
451 "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000452 reg_ctx_sp->HardwareSingleStep(true);
453 resume = true;
454 } else {
455 error.SetErrorStringWithFormat(
456 "KDP thread 0x%llx has no register context",
457 kernel_thread_sp->GetID());
458 }
459 } break;
Greg Clayton1afa68e2013-04-02 20:32:37 +0000460
Kate Stoneb9c1b512016-09-06 20:57:50 +0000461 case eStateRunning: {
462 lldb::RegisterContextSP reg_ctx_sp(
463 kernel_thread_sp->GetRegisterContext());
Greg Clayton97d5cf02012-09-25 02:40:06 +0000464
Kate Stoneb9c1b512016-09-06 20:57:50 +0000465 if (reg_ctx_sp) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000466 LLDB_LOGF(log, "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep "
467 "(false);");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000468 reg_ctx_sp->HardwareSingleStep(false);
469 resume = true;
470 } else {
471 error.SetErrorStringWithFormat(
472 "KDP thread 0x%llx has no register context",
473 kernel_thread_sp->GetID());
474 }
475 } break;
476
477 default:
478 // The only valid thread resume states are listed above
David Blaikiea322f362017-01-06 00:38:06 +0000479 llvm_unreachable("invalid thread resume state");
Greg Clayton7925fbb2012-09-21 16:31:20 +0000480 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000481 }
Greg Claytonf9765ac2011-07-15 03:27:12 +0000482
Kate Stoneb9c1b512016-09-06 20:57:50 +0000483 if (resume) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000484 LLDB_LOGF(log, "ProcessKDP::DoResume () sending resume");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000485
486 if (m_comm.SendRequestResume()) {
487 m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
488 SetPrivateState(eStateRunning);
489 } else
490 error.SetErrorString("KDP resume failed");
491 } else {
492 error.SetErrorString("kernel thread is suspended");
493 }
494
495 return error;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000496}
497
Kate Stoneb9c1b512016-09-06 20:57:50 +0000498lldb::ThreadSP ProcessKDP::GetKernelThread() {
499 // KDP only tells us about one thread/core. Any other threads will usually
500 // be the ones that are read from memory by the OS plug-ins.
501
502 ThreadSP thread_sp(m_kernel_thread_wp.lock());
503 if (!thread_sp) {
Jonas Devlieghere796ac802019-02-11 23:13:08 +0000504 thread_sp = std::make_shared<ThreadKDP>(*this, g_kernel_tid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000505 m_kernel_thread_wp = thread_sp;
506 }
507 return thread_sp;
508}
509
510bool ProcessKDP::UpdateThreadList(ThreadList &old_thread_list,
511 ThreadList &new_thread_list) {
512 // locker will keep a mutex locked until it goes out of scope
513 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD));
Pavel Labath250858a2017-02-06 21:46:22 +0000514 LLDB_LOGV(log, "pid = {0}", GetID());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515
516 // Even though there is a CPU mask, it doesn't mean we can see each CPU
517 // individually, there is really only one. Lets call this thread 1.
518 ThreadSP thread_sp(
519 old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
520 if (!thread_sp)
521 thread_sp = GetKernelThread();
522 new_thread_list.AddThread(thread_sp);
523
524 return new_thread_list.GetSize(false) > 0;
525}
526
527void ProcessKDP::RefreshStateAfterStop() {
Adrian Prantl05097242018-04-30 16:49:04 +0000528 // Let all threads recover from stopping and do any clean up based on the
529 // previous thread state (if any).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530 m_thread_list.RefreshStateAfterStop();
531}
532
Zachary Turner97206d52017-05-12 04:51:55 +0000533Status ProcessKDP::DoHalt(bool &caused_stop) {
534 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535
536 if (m_comm.IsRunning()) {
537 if (m_destroy_in_process) {
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000538 // If we are attempting to destroy, we need to not return an error to Halt
Adrian Prantl05097242018-04-30 16:49:04 +0000539 // or DoDestroy won't get called. We are also currently running, so send
540 // a process stopped event
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541 SetPrivateState(eStateStopped);
542 } else {
543 error.SetErrorString("KDP cannot interrupt a running kernel");
544 }
545 }
546 return error;
547}
548
Zachary Turner97206d52017-05-12 04:51:55 +0000549Status ProcessKDP::DoDetach(bool keep_stopped) {
550 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000552 LLDB_LOGF(log, "ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000553
554 if (m_comm.IsRunning()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000555 // We are running and we can't interrupt a running kernel, so we need to
556 // just close the connection to the kernel and hope for the best
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557 } else {
558 // If we are going to keep the target stopped, then don't send the
559 // disconnect message.
560 if (!keep_stopped && m_comm.IsConnected()) {
561 const bool success = m_comm.SendRequestDisconnect();
562 if (log) {
563 if (success)
564 log->PutCString(
565 "ProcessKDP::DoDetach() detach packet sent successfully");
566 else
567 log->PutCString(
568 "ProcessKDP::DoDetach() connection channel shutdown failed");
569 }
570 m_comm.Disconnect();
571 }
572 }
573 StopAsyncThread();
574 m_comm.Clear();
575
576 SetPrivateState(eStateDetached);
577 ResumePrivateStateThread();
578
579 // KillDebugserverProcess ();
580 return error;
581}
582
Zachary Turner97206d52017-05-12 04:51:55 +0000583Status ProcessKDP::DoDestroy() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000584 // For KDP there really is no difference between destroy and detach
585 bool keep_stopped = false;
586 return DoDetach(keep_stopped);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000587}
588
Greg Claytonf9765ac2011-07-15 03:27:12 +0000589// Process Queries
Greg Claytonf9765ac2011-07-15 03:27:12 +0000590
Kate Stoneb9c1b512016-09-06 20:57:50 +0000591bool ProcessKDP::IsAlive() {
592 return m_comm.IsConnected() && Process::IsAlive();
Greg Claytonf9765ac2011-07-15 03:27:12 +0000593}
594
Greg Claytonf9765ac2011-07-15 03:27:12 +0000595// Process Memory
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size,
Zachary Turner97206d52017-05-12 04:51:55 +0000597 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598 uint8_t *data_buffer = (uint8_t *)buf;
599 if (m_comm.IsConnected()) {
600 const size_t max_read_size = 512;
601 size_t total_bytes_read = 0;
Jason Molenda8eb32812014-05-21 23:44:02 +0000602
Kate Stoneb9c1b512016-09-06 20:57:50 +0000603 // Read the requested amount of memory in 512 byte chunks
604 while (total_bytes_read < size) {
605 size_t bytes_to_read_this_request = size - total_bytes_read;
606 if (bytes_to_read_this_request > max_read_size) {
607 bytes_to_read_this_request = max_read_size;
608 }
609 size_t bytes_read = m_comm.SendRequestReadMemory(
610 addr + total_bytes_read, data_buffer + total_bytes_read,
611 bytes_to_read_this_request, error);
612 total_bytes_read += bytes_read;
613 if (error.Fail() || bytes_read == 0) {
Jason Molenda8eb32812014-05-21 23:44:02 +0000614 return total_bytes_read;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615 }
Jason Molenda8eb32812014-05-21 23:44:02 +0000616 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000617
618 return total_bytes_read;
619 }
620 error.SetErrorString("not connected");
621 return 0;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000622}
623
Kate Stoneb9c1b512016-09-06 20:57:50 +0000624size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
Zachary Turner97206d52017-05-12 04:51:55 +0000625 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000626 if (m_comm.IsConnected())
627 return m_comm.SendRequestWriteMemory(addr, buf, size, error);
628 error.SetErrorString("not connected");
629 return 0;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000630}
631
Kate Stoneb9c1b512016-09-06 20:57:50 +0000632lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
Zachary Turner97206d52017-05-12 04:51:55 +0000633 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000634 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000635 "memory allocation not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000636 return LLDB_INVALID_ADDRESS;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000637}
638
Zachary Turner97206d52017-05-12 04:51:55 +0000639Status ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) {
640 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000641 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000642 "memory deallocation not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000643 return error;
644}
645
Zachary Turner97206d52017-05-12 04:51:55 +0000646Status ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000647 if (m_comm.LocalBreakpointsAreSupported()) {
Zachary Turner97206d52017-05-12 04:51:55 +0000648 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000649 if (!bp_site->IsEnabled()) {
650 if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) {
651 bp_site->SetEnabled(true);
652 bp_site->SetType(BreakpointSite::eExternal);
653 } else {
654 error.SetErrorString("KDP set breakpoint failed");
655 }
656 }
Greg Claytonf9765ac2011-07-15 03:27:12 +0000657 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658 }
659 return EnableSoftwareBreakpoint(bp_site);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000660}
661
Zachary Turner97206d52017-05-12 04:51:55 +0000662Status ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000663 if (m_comm.LocalBreakpointsAreSupported()) {
Zachary Turner97206d52017-05-12 04:51:55 +0000664 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000665 if (bp_site->IsEnabled()) {
666 BreakpointSite::Type bp_type = bp_site->GetType();
667 if (bp_type == BreakpointSite::eExternal) {
668 if (m_destroy_in_process && m_comm.IsRunning()) {
669 // We are trying to destroy our connection and we are running
670 bp_site->SetEnabled(false);
671 } else {
672 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
673 bp_site->SetEnabled(false);
674 else
675 error.SetErrorString("KDP remove breakpoint failed");
Greg Clayton5b882162011-07-21 01:12:01 +0000676 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000677 } else {
678 error = DisableSoftwareBreakpoint(bp_site);
679 }
Greg Clayton07e66e32011-07-20 03:41:06 +0000680 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000681 return error;
682 }
683 return DisableSoftwareBreakpoint(bp_site);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000684}
685
Zachary Turner97206d52017-05-12 04:51:55 +0000686Status ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) {
687 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000688 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000689 "watchpoints are not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 return error;
691}
692
Zachary Turner97206d52017-05-12 04:51:55 +0000693Status ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) {
694 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000695 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000696 "watchpoints are not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697 return error;
698}
699
700void ProcessKDP::Clear() { m_thread_list.Clear(); }
701
Zachary Turner97206d52017-05-12 04:51:55 +0000702Status ProcessKDP::DoSignal(int signo) {
703 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000704 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000705 "sending signals is not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000706 return error;
707}
708
709void ProcessKDP::Initialize() {
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000710 static llvm::once_flag g_once_flag;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000712 llvm::call_once(g_once_flag, []() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000713 PluginManager::RegisterPlugin(GetPluginNameStatic(),
714 GetPluginDescriptionStatic(), CreateInstance,
715 DebuggerInitialize);
716
Pavel Labath7b35b782017-02-17 15:08:08 +0000717 ProcessKDPLog::Initialize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000718 });
719}
720
721void ProcessKDP::DebuggerInitialize(lldb_private::Debugger &debugger) {
722 if (!PluginManager::GetSettingForProcessPlugin(
723 debugger, PluginProperties::GetSettingName())) {
724 const bool is_global_setting = true;
725 PluginManager::CreateSettingForProcessPlugin(
726 debugger, GetGlobalPluginProperties()->GetValueProperties(),
727 ConstString("Properties for the kdp-remote process plug-in."),
728 is_global_setting);
729 }
730}
731
732bool ProcessKDP::StartAsyncThread() {
733 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
734
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000735 LLDB_LOGF(log, "ProcessKDP::StartAsyncThread ()");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000736
737 if (m_async_thread.IsJoinable())
738 return true;
739
Jonas Devliegheref39c2e12019-07-05 17:42:08 +0000740 llvm::Expected<HostThread> async_thread = ThreadLauncher::LaunchThread(
741 "<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this);
742 if (!async_thread) {
743 LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST),
744 "failed to launch host thread: {}",
745 llvm::toString(async_thread.takeError()));
746 return false;
747 }
748 m_async_thread = *async_thread;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000749 return m_async_thread.IsJoinable();
750}
751
752void ProcessKDP::StopAsyncThread() {
753 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
754
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000755 LLDB_LOGF(log, "ProcessKDP::StopAsyncThread ()");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000756
757 m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
758
759 // Stop the stdio thread
760 if (m_async_thread.IsJoinable())
761 m_async_thread.Join(nullptr);
762}
763
764void *ProcessKDP::AsyncThread(void *arg) {
765 ProcessKDP *process = (ProcessKDP *)arg;
766
767 const lldb::pid_t pid = process->GetID();
768
769 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000770 LLDB_LOGF(log,
771 "ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
772 ") thread starting...",
773 arg, pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000774
775 ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
776 EventSP event_sp;
777 const uint32_t desired_event_mask =
778 eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
779
780 if (listener_sp->StartListeningForEvents(&process->m_async_broadcaster,
781 desired_event_mask) ==
782 desired_event_mask) {
783 bool done = false;
784 while (!done) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000785 LLDB_LOGF(log,
786 "ProcessKDP::AsyncThread (pid = %" PRIu64
787 ") listener.WaitForEvent (NULL, event_sp)...",
788 pid);
Pavel Labathfafff0c2016-11-30 11:09:47 +0000789 if (listener_sp->GetEvent(event_sp, llvm::None)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000790 uint32_t event_type = event_sp->GetType();
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000791 LLDB_LOGF(log,
792 "ProcessKDP::AsyncThread (pid = %" PRIu64
793 ") Got an event of type: %d...",
794 pid, event_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795
796 // When we are running, poll for 1 second to try and get an exception
797 // to indicate the process has stopped. If we don't get one, check to
798 // make sure no one asked us to exit
799 bool is_running = false;
800 DataExtractor exc_reply_packet;
801 do {
802 switch (event_type) {
803 case eBroadcastBitAsyncContinue: {
804 is_running = true;
805 if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds(
806 exc_reply_packet, 1 * USEC_PER_SEC)) {
807 ThreadSP thread_sp(process->GetKernelThread());
808 if (thread_sp) {
809 lldb::RegisterContextSP reg_ctx_sp(
810 thread_sp->GetRegisterContext());
811 if (reg_ctx_sp)
812 reg_ctx_sp->InvalidateAllRegisters();
813 static_cast<ThreadKDP *>(thread_sp.get())
814 ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet);
815 }
816
817 // TODO: parse the stop reply packet
818 is_running = false;
819 process->SetPrivateState(eStateStopped);
820 } else {
821 // Check to see if we are supposed to exit. There is no way to
822 // interrupt a running kernel, so all we can do is wait for an
823 // exception or detach...
Pavel Labathfafff0c2016-11-30 11:09:47 +0000824 if (listener_sp->GetEvent(event_sp,
825 std::chrono::microseconds(0))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826 // We got an event, go through the loop again
827 event_type = event_sp->GetType();
828 }
Greg Clayton5b882162011-07-21 01:12:01 +0000829 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000830 } break;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000831
Kate Stoneb9c1b512016-09-06 20:57:50 +0000832 case eBroadcastBitAsyncThreadShouldExit:
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000833 LLDB_LOGF(log,
834 "ProcessKDP::AsyncThread (pid = %" PRIu64
835 ") got eBroadcastBitAsyncThreadShouldExit...",
836 pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000837 done = true;
838 is_running = false;
839 break;
Greg Clayton97d5cf02012-09-25 02:40:06 +0000840
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841 default:
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000842 LLDB_LOGF(log,
843 "ProcessKDP::AsyncThread (pid = %" PRIu64
844 ") got unknown event 0x%8.8x",
845 pid, event_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846 done = true;
847 is_running = false;
848 break;
849 }
850 } while (is_running);
851 } else {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000852 LLDB_LOGF(log,
853 "ProcessKDP::AsyncThread (pid = %" PRIu64
854 ") listener.WaitForEvent (NULL, event_sp) => false",
855 pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000856 done = true;
857 }
Greg Claytonf9765ac2011-07-15 03:27:12 +0000858 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000859 }
Zachary Turner39de3112014-09-09 20:54:56 +0000860
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000861 LLDB_LOGF(log,
862 "ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
863 ") thread exiting...",
864 arg, pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865
866 process->m_async_thread.Reset();
867 return NULL;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000868}
869
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870class CommandObjectProcessKDPPacketSend : public CommandObjectParsed {
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000871private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 OptionGroupOptions m_option_group;
873 OptionGroupUInt64 m_command_byte;
874 OptionGroupString m_packet_data;
875
876 virtual Options *GetOptions() { return &m_option_group; }
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000877
878public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000879 CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter)
880 : CommandObjectParsed(interpreter, "process plugin packet send",
881 "Send a custom packet through the KDP protocol by "
882 "specifying the command byte and the packet "
883 "payload data. A packet will be sent with a "
884 "correct header and payload, and the raw result "
885 "bytes will be displayed as a string value. ",
886 NULL),
Todd Fialae1cfbc72016-08-11 23:51:28 +0000887 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000888 m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone,
889 "Specify the command byte to use when sending the KDP "
890 "request packet.",
891 0),
892 m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone,
893 "Specify packet payload bytes as a hex ASCII string with "
894 "no spaces or hex prefixes.",
895 NULL) {
896 m_option_group.Append(&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
897 m_option_group.Append(&m_packet_data, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
898 m_option_group.Finalize();
899 }
900
901 ~CommandObjectProcessKDPPacketSend() {}
902
903 bool DoExecute(Args &command, CommandReturnObject &result) {
904 const size_t argc = command.GetArgumentCount();
905 if (argc == 0) {
906 if (!m_command_byte.GetOptionValue().OptionWasSet()) {
907 result.AppendError(
908 "the --command option must be set to a valid command byte");
909 result.SetStatus(eReturnStatusFailed);
910 } else {
911 const uint64_t command_byte =
912 m_command_byte.GetOptionValue().GetUInt64Value(0);
913 if (command_byte > 0 && command_byte <= UINT8_MAX) {
914 ProcessKDP *process =
915 (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
916 if (process) {
917 const StateType state = process->GetState();
918
919 if (StateIsStoppedState(state, true)) {
920 std::vector<uint8_t> payload_bytes;
921 const char *ascii_hex_bytes_cstr =
922 m_packet_data.GetOptionValue().GetCurrentValue();
923 if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) {
924 StringExtractor extractor(ascii_hex_bytes_cstr);
925 const size_t ascii_hex_bytes_cstr_len =
926 extractor.GetStringRef().size();
927 if (ascii_hex_bytes_cstr_len & 1) {
928 result.AppendErrorWithFormat("payload data must contain an "
929 "even number of ASCII hex "
930 "characters: '%s'",
931 ascii_hex_bytes_cstr);
932 result.SetStatus(eReturnStatusFailed);
933 return false;
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000934 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);
936 if (extractor.GetHexBytes(payload_bytes, '\xdd') !=
937 payload_bytes.size()) {
938 result.AppendErrorWithFormat("payload data must only contain "
939 "ASCII hex characters (no "
940 "spaces or hex prefixes): '%s'",
941 ascii_hex_bytes_cstr);
942 result.SetStatus(eReturnStatusFailed);
943 return false;
944 }
945 }
Zachary Turner97206d52017-05-12 04:51:55 +0000946 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947 DataExtractor reply;
948 process->GetCommunication().SendRawRequest(
949 command_byte,
950 payload_bytes.empty() ? NULL : payload_bytes.data(),
951 payload_bytes.size(), reply, error);
952
953 if (error.Success()) {
954 // Copy the binary bytes into a hex ASCII string for the result
955 StreamString packet;
956 packet.PutBytesAsRawHex8(
957 reply.GetDataStart(), reply.GetByteSize(),
958 endian::InlHostByteOrder(), endian::InlHostByteOrder());
Zachary Turnerc1564272016-11-16 21:15:24 +0000959 result.AppendMessage(packet.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000960 result.SetStatus(eReturnStatusSuccessFinishResult);
961 return true;
962 } else {
963 const char *error_cstr = error.AsCString();
964 if (error_cstr && error_cstr[0])
965 result.AppendError(error_cstr);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000966 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000967 result.AppendErrorWithFormat("unknown error 0x%8.8x",
968 error.GetError());
969 result.SetStatus(eReturnStatusFailed);
970 return false;
971 }
972 } else {
973 result.AppendErrorWithFormat("process must be stopped in order "
974 "to send KDP packets, state is %s",
975 StateAsCString(state));
976 result.SetStatus(eReturnStatusFailed);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000977 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000978 } else {
979 result.AppendError("invalid process");
980 result.SetStatus(eReturnStatusFailed);
981 }
982 } else {
983 result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
984 ", valid values are 1 - 255",
985 command_byte);
986 result.SetStatus(eReturnStatusFailed);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000987 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000988 }
989 } else {
990 result.AppendErrorWithFormat("'%s' takes no arguments, only options.",
991 m_cmd_name.c_str());
992 result.SetStatus(eReturnStatusFailed);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000993 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000994 return false;
995 }
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000996};
997
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998class CommandObjectProcessKDPPacket : public CommandObjectMultiword {
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000999private:
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001000public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001001 CommandObjectProcessKDPPacket(CommandInterpreter &interpreter)
1002 : CommandObjectMultiword(interpreter, "process plugin packet",
1003 "Commands that deal with KDP remote packets.",
1004 NULL) {
1005 LoadSubCommand(
1006 "send",
1007 CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter)));
1008 }
1009
1010 ~CommandObjectProcessKDPPacket() {}
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001011};
1012
Kate Stoneb9c1b512016-09-06 20:57:50 +00001013class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword {
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001014public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
1016 : CommandObjectMultiword(
1017 interpreter, "process plugin",
1018 "Commands for operating on a ProcessKDP process.",
1019 "process plugin <subcommand> [<subcommand-options>]") {
1020 LoadSubCommand("packet", CommandObjectSP(new CommandObjectProcessKDPPacket(
1021 interpreter)));
1022 }
1023
1024 ~CommandObjectMultiwordProcessKDP() {}
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001025};
1026
Kate Stoneb9c1b512016-09-06 20:57:50 +00001027CommandObject *ProcessKDP::GetPluginCommandObject() {
1028 if (!m_command_sp)
Jonas Devlieghere796ac802019-02-11 23:13:08 +00001029 m_command_sp = std::make_shared<CommandObjectMultiwordProcessKDP>(
1030 GetTarget().GetDebugger().GetCommandInterpreter());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031 return m_command_sp.get();
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001032}