blob: ef13bd733466a33736d3c9480ecc9dbf998395db [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
Benjamin Kramer3f69fa62015-04-03 10:55:00 +000012#include <mutex>
13
Greg Clayton07e66e32011-07-20 03:41:06 +000014#include "lldb/Core/Debugger.h"
Greg Clayton1f746072012-08-29 21:13:06 +000015#include "lldb/Core/Module.h"
Jason Molenda4bd4e7e2012-09-29 04:02:01 +000016#include "lldb/Core/ModuleSpec.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000017#include "lldb/Core/PluginManager.h"
Zachary Turner93a66fc2014-10-06 21:22:36 +000018#include "lldb/Host/ConnectionFileDescriptor.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000019#include "lldb/Host/Host.h"
Jason Molenda4bd4e7e2012-09-29 04:02:01 +000020#include "lldb/Host/Symbols.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"
Greg Clayton1f746072012-08-29 21:13:06 +000030#include "lldb/Symbol/ObjectFile.h"
Greg Clayton7925fbb2012-09-21 16:31:20 +000031#include "lldb/Target/RegisterContext.h"
Greg Clayton57508022011-07-15 16:31:38 +000032#include "lldb/Target/Target.h"
Greg Claytona63d08c2011-07-19 03:57:15 +000033#include "lldb/Target/Thread.h"
Pavel Labathd821c992018-08-07 11:07:21 +000034#include "lldb/Utility/State.h"
Bruce Mitchener45788152015-07-07 23:59:01 +000035#include "lldb/Utility/StringExtractor.h"
Pavel Labathd821c992018-08-07 11:07:21 +000036#include "lldb/Utility/UUID.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000037
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000038#include "llvm/Support/Threading.h"
39
Charles Davis510938e2013-08-27 05:04:57 +000040#define USEC_PER_SEC 1000000
41
Kate Stoneb9c1b512016-09-06 20:57:50 +000042#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
43#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000044#include "ProcessKDP.h"
45#include "ProcessKDPLog.h"
Greg Claytona63d08c2011-07-19 03:57:15 +000046#include "ThreadKDP.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000047
48using namespace lldb;
49using namespace lldb_private;
50
Greg Clayton7f982402013-07-15 22:54:20 +000051namespace {
52
Tatyana Krasnukhae40db052018-09-27 07:11:58 +000053static constexpr PropertyDefinition g_properties[] = {
Tatyana Krasnukhaf929e2b2018-09-26 20:31:39 +000054 {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, {},
Tatyana Krasnukhae40db052018-09-27 07:11:58 +000055 "Specify the default packet timeout in seconds."}};
Greg Clayton7f982402013-07-15 22:54:20 +000056
Kate Stoneb9c1b512016-09-06 20:57:50 +000057enum { ePropertyPacketTimeout };
Greg Clayton7f982402013-07-15 22:54:20 +000058
Kate Stoneb9c1b512016-09-06 20:57:50 +000059class PluginProperties : public Properties {
60public:
61 static ConstString GetSettingName() {
62 return ProcessKDP::GetPluginNameStatic();
63 }
Greg Clayton7f982402013-07-15 22:54:20 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 PluginProperties() : Properties() {
66 m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
67 m_collection_sp->Initialize(g_properties);
68 }
Greg Clayton7f982402013-07-15 22:54:20 +000069
Kate Stoneb9c1b512016-09-06 20:57:50 +000070 virtual ~PluginProperties() {}
71
72 uint64_t GetPacketTimeout() {
73 const uint32_t idx = ePropertyPacketTimeout;
74 return m_collection_sp->GetPropertyAtIndexAsUInt64(
75 NULL, idx, g_properties[idx].default_uint_value);
76 }
77};
78
79typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
80
81static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
82 static ProcessKDPPropertiesSP g_settings_sp;
83 if (!g_settings_sp)
84 g_settings_sp.reset(new PluginProperties());
85 return g_settings_sp;
86}
87
Greg Clayton7f982402013-07-15 22:54:20 +000088} // anonymous namespace end
89
Andrew Kaylorba4e61d2013-05-07 18:35:34 +000090static const lldb::tid_t g_kernel_tid = 1;
91
Kate Stoneb9c1b512016-09-06 20:57:50 +000092ConstString ProcessKDP::GetPluginNameStatic() {
93 static ConstString g_name("kdp-remote");
94 return g_name;
Greg Claytonf9765ac2011-07-15 03:27:12 +000095}
96
Kate Stoneb9c1b512016-09-06 20:57:50 +000097const char *ProcessKDP::GetPluginDescriptionStatic() {
98 return "KDP Remote protocol based debugging plug-in for darwin kernel "
99 "debugging.";
Greg Claytonf9765ac2011-07-15 03:27:12 +0000100}
101
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102void ProcessKDP::Terminate() {
103 PluginManager::UnregisterPlugin(ProcessKDP::CreateInstance);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000104}
105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106lldb::ProcessSP ProcessKDP::CreateInstance(TargetSP target_sp,
107 ListenerSP listener_sp,
108 const FileSpec *crash_file_path) {
109 lldb::ProcessSP process_sp;
110 if (crash_file_path == NULL)
111 process_sp.reset(new ProcessKDP(target_sp, listener_sp));
112 return process_sp;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000113}
114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
116 if (plugin_specified_by_name)
117 return true;
Greg Clayton596ed242011-10-21 21:41:45 +0000118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 // For now we are just making sure the file exists for a given module
120 Module *exe_module = target_sp->GetExecutableModulePointer();
121 if (exe_module) {
122 const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
123 switch (triple_ref.getOS()) {
124 case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for
125 // iOS, but accept darwin just in case
126 case llvm::Triple::MacOSX: // For desktop targets
127 case llvm::Triple::IOS: // For arm targets
128 case llvm::Triple::TvOS:
129 case llvm::Triple::WatchOS:
130 if (triple_ref.getVendor() == llvm::Triple::Apple) {
131 ObjectFile *exe_objfile = exe_module->GetObjectFile();
132 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
133 exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
134 return true;
135 }
136 break;
Greg Clayton70512312012-05-08 01:45:38 +0000137
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138 default:
139 break;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000140 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141 }
142 return false;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000143}
144
145//----------------------------------------------------------------------
146// ProcessKDP constructor
147//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp)
149 : Process(target_sp, listener_sp),
150 m_comm("lldb.process.kdp-remote.communication"),
151 m_async_broadcaster(NULL, "lldb.process.kdp-remote.async-broadcaster"),
152 m_dyld_plugin_name(), m_kernel_load_addr(LLDB_INVALID_ADDRESS),
153 m_command_sp(), m_kernel_thread_wp() {
154 m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
155 "async thread should exit");
156 m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
157 "async thread continue");
158 const uint64_t timeout_seconds =
159 GetGlobalPluginProperties()->GetPacketTimeout();
160 if (timeout_seconds > 0)
Pavel Labath5cddd602016-11-02 10:13:54 +0000161 m_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
Greg Claytonf9765ac2011-07-15 03:27:12 +0000162}
163
164//----------------------------------------------------------------------
165// Destructor
166//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167ProcessKDP::~ProcessKDP() {
168 Clear();
Adrian Prantl05097242018-04-30 16:49:04 +0000169 // We need to call finalize on the process before destroying ourselves to
170 // make sure all of the broadcaster cleanup goes as planned. If we destruct
171 // this class, then Process::~Process() might have problems trying to fully
172 // destroy the broadcaster.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 Finalize();
Greg Claytonf9765ac2011-07-15 03:27:12 +0000174}
175
176//----------------------------------------------------------------------
177// PluginInterface
178//----------------------------------------------------------------------
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
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 std::unique_ptr<ConnectionFileDescriptor> conn_ap(
234 new ConnectionFileDescriptor());
235 if (conn_ap.get()) {
236 // 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) {
241 if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
242 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
Kate Stoneb9c1b512016-09-06 20:57:50 +0000247 if (conn_ap->IsConnected()) {
248 const TCPSocket &socket =
249 static_cast<const TCPSocket &>(*conn_ap->GetReadObject());
250 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) {
253 m_comm.SetConnection(conn_ap.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
293 module_spec.GetSymbolFileSpec() =
294 Symbols::LocateExecutableSymbolFile(module_spec);
295 if (module_spec.GetSymbolFileSpec()) {
296 ModuleSpec executable_module_spec =
297 Symbols::LocateExecutableObjectFile(module_spec);
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000298 if (FileSystem::Instance().Exists(
299 executable_module_spec.GetFileSpec())) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000300 module_spec.GetFileSpec() =
301 executable_module_spec.GetFileSpec();
Greg Clayton3a29bdb2011-07-17 20:36:25 +0000302 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303 }
304 if (!module_spec.GetSymbolFileSpec() ||
305 !module_spec.GetSymbolFileSpec())
306 Symbols::DownloadObjectAndSymbolFile(module_spec, true);
Greg Clayton3a29bdb2011-07-17 20:36:25 +0000307
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000308 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000309 ModuleSP module_sp(new Module(module_spec));
310 if (module_sp.get() && module_sp->GetObjectFile()) {
311 // Get the current target executable
312 ModuleSP exe_module_sp(target.GetExecutableModule());
313
314 // Make sure you don't already have the right module loaded
315 // and they will be uniqued
316 if (exe_module_sp.get() != module_sp.get())
Jonas Devliegheref9a07e92018-09-20 09:09:05 +0000317 target.SetExecutableModule(module_sp, eLoadDependentsNo);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 }
319 }
320 }
321 } else if (m_comm.RemoteIsDarwinKernel()) {
322 m_dyld_plugin_name =
323 DynamicLoaderDarwinKernel::GetPluginNameStatic();
324 if (kernel_load_addr != LLDB_INVALID_ADDRESS) {
325 m_kernel_load_addr = kernel_load_addr;
326 }
327 }
328
329 // Set the thread ID
330 UpdateThreadListIfNeeded();
331 SetID(1);
332 GetThreadList();
333 SetPrivateState(eStateStopped);
334 StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream());
335 if (async_strm_sp) {
336 const char *cstr;
337 if ((cstr = m_comm.GetKernelVersion()) != NULL) {
338 async_strm_sp->Printf("Version: %s\n", cstr);
339 async_strm_sp->Flush();
340 }
341 // if ((cstr = m_comm.GetImagePath ()) != NULL)
342 // {
343 // async_strm_sp->Printf ("Image Path:
344 // %s\n", cstr);
345 // async_strm_sp->Flush();
346 // }
347 }
348 } else {
349 error.SetErrorString("KDP_REATTACH failed");
350 }
351 } else {
352 error.SetErrorString("KDP_REATTACH failed");
353 }
354 } else {
355 error.SetErrorString("invalid reply port from UDP connection");
356 }
357 } else {
358 if (error.Success())
Greg Clayton3ce7e992016-12-07 23:51:49 +0000359 error.SetErrorStringWithFormat("failed to connect to '%s'",
360 remote_url.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 }
362 if (error.Fail())
363 m_comm.Disconnect();
364
365 return error;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000366}
367
368//----------------------------------------------------------------------
369// Process Control
370//----------------------------------------------------------------------
Zachary Turner97206d52017-05-12 04:51:55 +0000371Status ProcessKDP::DoLaunch(Module *exe_module,
372 ProcessLaunchInfo &launch_info) {
373 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374 error.SetErrorString("launching not supported in kdp-remote plug-in");
375 return error;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000376}
377
Zachary Turner97206d52017-05-12 04:51:55 +0000378Status
379ProcessKDP::DoAttachToProcessWithID(lldb::pid_t attach_pid,
380 const ProcessAttachInfo &attach_info) {
381 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000383 "attach to process by ID is not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000384 return error;
Han Ming Ong84647042012-02-25 01:07:38 +0000385}
386
Zachary Turner97206d52017-05-12 04:51:55 +0000387Status
388ProcessKDP::DoAttachToProcessWithName(const char *process_name,
389 const ProcessAttachInfo &attach_info) {
390 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000391 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000392 "attach to process by name is not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393 return error;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000394}
395
Kate Stoneb9c1b512016-09-06 20:57:50 +0000396void ProcessKDP::DidAttach(ArchSpec &process_arch) {
397 Process::DidAttach(process_arch);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000398
Kate Stoneb9c1b512016-09-06 20:57:50 +0000399 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
400 if (log)
401 log->Printf("ProcessKDP::DidAttach()");
402 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() {
410 if (m_dyld_ap.get() == NULL)
411 m_dyld_ap.reset(DynamicLoader::FindPlugin(
412 this,
413 m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
414 return m_dyld_ap.get();
415}
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
Greg Claytonf9765ac2011-07-15 03:27:12 +0000435 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000436 log->Printf("ProcessKDP::DoResume() thread_resume_state = %s",
437 StateAsCString(thread_resume_state));
438 switch (thread_resume_state) {
439 case eStateSuspended:
Adrian Prantl05097242018-04-30 16:49:04 +0000440 // Nothing to do here when a thread will stay suspended we just leave the
441 // CPU mask bit set to zero for the thread
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 if (log)
443 log->Printf("ProcessKDP::DoResume() = suspended???");
444 break;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000445
Kate Stoneb9c1b512016-09-06 20:57:50 +0000446 case eStateStepping: {
447 lldb::RegisterContextSP reg_ctx_sp(
448 kernel_thread_sp->GetRegisterContext());
Jason Molenda5e8534e2012-10-03 01:29:34 +0000449
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450 if (reg_ctx_sp) {
Greg Clayton6e0ff1a2013-05-09 01:55:29 +0000451 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000452 log->Printf(
453 "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
454 reg_ctx_sp->HardwareSingleStep(true);
455 resume = true;
456 } else {
457 error.SetErrorStringWithFormat(
458 "KDP thread 0x%llx has no register context",
459 kernel_thread_sp->GetID());
460 }
461 } break;
Greg Clayton1afa68e2013-04-02 20:32:37 +0000462
Kate Stoneb9c1b512016-09-06 20:57:50 +0000463 case eStateRunning: {
464 lldb::RegisterContextSP reg_ctx_sp(
465 kernel_thread_sp->GetRegisterContext());
Greg Clayton97d5cf02012-09-25 02:40:06 +0000466
Kate Stoneb9c1b512016-09-06 20:57:50 +0000467 if (reg_ctx_sp) {
Greg Clayton97d5cf02012-09-25 02:40:06 +0000468 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000469 log->Printf("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep "
470 "(false);");
471 reg_ctx_sp->HardwareSingleStep(false);
472 resume = true;
473 } else {
474 error.SetErrorStringWithFormat(
475 "KDP thread 0x%llx has no register context",
476 kernel_thread_sp->GetID());
477 }
478 } break;
479
480 default:
481 // The only valid thread resume states are listed above
David Blaikiea322f362017-01-06 00:38:06 +0000482 llvm_unreachable("invalid thread resume state");
Greg Clayton7925fbb2012-09-21 16:31:20 +0000483 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000484 }
Greg Claytonf9765ac2011-07-15 03:27:12 +0000485
Kate Stoneb9c1b512016-09-06 20:57:50 +0000486 if (resume) {
Greg Claytonf9765ac2011-07-15 03:27:12 +0000487 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000488 log->Printf("ProcessKDP::DoResume () sending resume");
489
490 if (m_comm.SendRequestResume()) {
491 m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
492 SetPrivateState(eStateRunning);
493 } else
494 error.SetErrorString("KDP resume failed");
495 } else {
496 error.SetErrorString("kernel thread is suspended");
497 }
498
499 return error;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000500}
501
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502lldb::ThreadSP ProcessKDP::GetKernelThread() {
503 // KDP only tells us about one thread/core. Any other threads will usually
504 // be the ones that are read from memory by the OS plug-ins.
505
506 ThreadSP thread_sp(m_kernel_thread_wp.lock());
507 if (!thread_sp) {
508 thread_sp.reset(new ThreadKDP(*this, g_kernel_tid));
509 m_kernel_thread_wp = thread_sp;
510 }
511 return thread_sp;
512}
513
514bool ProcessKDP::UpdateThreadList(ThreadList &old_thread_list,
515 ThreadList &new_thread_list) {
516 // locker will keep a mutex locked until it goes out of scope
517 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD));
Pavel Labath250858a2017-02-06 21:46:22 +0000518 LLDB_LOGV(log, "pid = {0}", GetID());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000519
520 // Even though there is a CPU mask, it doesn't mean we can see each CPU
521 // individually, there is really only one. Lets call this thread 1.
522 ThreadSP thread_sp(
523 old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
524 if (!thread_sp)
525 thread_sp = GetKernelThread();
526 new_thread_list.AddThread(thread_sp);
527
528 return new_thread_list.GetSize(false) > 0;
529}
530
531void ProcessKDP::RefreshStateAfterStop() {
Adrian Prantl05097242018-04-30 16:49:04 +0000532 // Let all threads recover from stopping and do any clean up based on the
533 // previous thread state (if any).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534 m_thread_list.RefreshStateAfterStop();
535}
536
Zachary Turner97206d52017-05-12 04:51:55 +0000537Status ProcessKDP::DoHalt(bool &caused_stop) {
538 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000539
540 if (m_comm.IsRunning()) {
541 if (m_destroy_in_process) {
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000542 // If we are attempting to destroy, we need to not return an error to Halt
Adrian Prantl05097242018-04-30 16:49:04 +0000543 // or DoDestroy won't get called. We are also currently running, so send
544 // a process stopped event
Kate Stoneb9c1b512016-09-06 20:57:50 +0000545 SetPrivateState(eStateStopped);
546 } else {
547 error.SetErrorString("KDP cannot interrupt a running kernel");
548 }
549 }
550 return error;
551}
552
Zachary Turner97206d52017-05-12 04:51:55 +0000553Status ProcessKDP::DoDetach(bool keep_stopped) {
554 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000555 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
556 if (log)
557 log->Printf("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
558
559 if (m_comm.IsRunning()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000560 // We are running and we can't interrupt a running kernel, so we need to
561 // just close the connection to the kernel and hope for the best
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562 } else {
563 // If we are going to keep the target stopped, then don't send the
564 // disconnect message.
565 if (!keep_stopped && m_comm.IsConnected()) {
566 const bool success = m_comm.SendRequestDisconnect();
567 if (log) {
568 if (success)
569 log->PutCString(
570 "ProcessKDP::DoDetach() detach packet sent successfully");
571 else
572 log->PutCString(
573 "ProcessKDP::DoDetach() connection channel shutdown failed");
574 }
575 m_comm.Disconnect();
576 }
577 }
578 StopAsyncThread();
579 m_comm.Clear();
580
581 SetPrivateState(eStateDetached);
582 ResumePrivateStateThread();
583
584 // KillDebugserverProcess ();
585 return error;
586}
587
Zachary Turner97206d52017-05-12 04:51:55 +0000588Status ProcessKDP::DoDestroy() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589 // For KDP there really is no difference between destroy and detach
590 bool keep_stopped = false;
591 return DoDetach(keep_stopped);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000592}
593
594//------------------------------------------------------------------
595// Process Queries
596//------------------------------------------------------------------
597
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598bool ProcessKDP::IsAlive() {
599 return m_comm.IsConnected() && Process::IsAlive();
Greg Claytonf9765ac2011-07-15 03:27:12 +0000600}
601
602//------------------------------------------------------------------
603// Process Memory
604//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size,
Zachary Turner97206d52017-05-12 04:51:55 +0000606 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000607 uint8_t *data_buffer = (uint8_t *)buf;
608 if (m_comm.IsConnected()) {
609 const size_t max_read_size = 512;
610 size_t total_bytes_read = 0;
Jason Molenda8eb32812014-05-21 23:44:02 +0000611
Kate Stoneb9c1b512016-09-06 20:57:50 +0000612 // Read the requested amount of memory in 512 byte chunks
613 while (total_bytes_read < size) {
614 size_t bytes_to_read_this_request = size - total_bytes_read;
615 if (bytes_to_read_this_request > max_read_size) {
616 bytes_to_read_this_request = max_read_size;
617 }
618 size_t bytes_read = m_comm.SendRequestReadMemory(
619 addr + total_bytes_read, data_buffer + total_bytes_read,
620 bytes_to_read_this_request, error);
621 total_bytes_read += bytes_read;
622 if (error.Fail() || bytes_read == 0) {
Jason Molenda8eb32812014-05-21 23:44:02 +0000623 return total_bytes_read;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000624 }
Jason Molenda8eb32812014-05-21 23:44:02 +0000625 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000626
627 return total_bytes_read;
628 }
629 error.SetErrorString("not connected");
630 return 0;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000631}
632
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
Zachary Turner97206d52017-05-12 04:51:55 +0000634 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000635 if (m_comm.IsConnected())
636 return m_comm.SendRequestWriteMemory(addr, buf, size, error);
637 error.SetErrorString("not connected");
638 return 0;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000639}
640
Kate Stoneb9c1b512016-09-06 20:57:50 +0000641lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
Zachary Turner97206d52017-05-12 04:51:55 +0000642 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000643 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000644 "memory allocation not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000645 return LLDB_INVALID_ADDRESS;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000646}
647
Zachary Turner97206d52017-05-12 04:51:55 +0000648Status ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) {
649 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000650 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000651 "memory deallocation not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000652 return error;
653}
654
Zachary Turner97206d52017-05-12 04:51:55 +0000655Status ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000656 if (m_comm.LocalBreakpointsAreSupported()) {
Zachary Turner97206d52017-05-12 04:51:55 +0000657 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658 if (!bp_site->IsEnabled()) {
659 if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) {
660 bp_site->SetEnabled(true);
661 bp_site->SetType(BreakpointSite::eExternal);
662 } else {
663 error.SetErrorString("KDP set breakpoint failed");
664 }
665 }
Greg Claytonf9765ac2011-07-15 03:27:12 +0000666 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000667 }
668 return EnableSoftwareBreakpoint(bp_site);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000669}
670
Zachary Turner97206d52017-05-12 04:51:55 +0000671Status ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000672 if (m_comm.LocalBreakpointsAreSupported()) {
Zachary Turner97206d52017-05-12 04:51:55 +0000673 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674 if (bp_site->IsEnabled()) {
675 BreakpointSite::Type bp_type = bp_site->GetType();
676 if (bp_type == BreakpointSite::eExternal) {
677 if (m_destroy_in_process && m_comm.IsRunning()) {
678 // We are trying to destroy our connection and we are running
679 bp_site->SetEnabled(false);
680 } else {
681 if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
682 bp_site->SetEnabled(false);
683 else
684 error.SetErrorString("KDP remove breakpoint failed");
Greg Clayton5b882162011-07-21 01:12:01 +0000685 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000686 } else {
687 error = DisableSoftwareBreakpoint(bp_site);
688 }
Greg Clayton07e66e32011-07-20 03:41:06 +0000689 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 return error;
691 }
692 return DisableSoftwareBreakpoint(bp_site);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000693}
694
Zachary Turner97206d52017-05-12 04:51:55 +0000695Status ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) {
696 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000698 "watchpoints are not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699 return error;
700}
701
Zachary Turner97206d52017-05-12 04:51:55 +0000702Status ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) {
703 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000704 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000705 "watchpoints are not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000706 return error;
707}
708
709void ProcessKDP::Clear() { m_thread_list.Clear(); }
710
Zachary Turner97206d52017-05-12 04:51:55 +0000711Status ProcessKDP::DoSignal(int signo) {
712 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000713 error.SetErrorString(
Bruce Mitchener4ebdee02018-05-29 09:10:46 +0000714 "sending signals is not supported in kdp remote debugging");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000715 return error;
716}
717
718void ProcessKDP::Initialize() {
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000719 static llvm::once_flag g_once_flag;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000720
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +0000721 llvm::call_once(g_once_flag, []() {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000722 PluginManager::RegisterPlugin(GetPluginNameStatic(),
723 GetPluginDescriptionStatic(), CreateInstance,
724 DebuggerInitialize);
725
Pavel Labath7b35b782017-02-17 15:08:08 +0000726 ProcessKDPLog::Initialize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727 });
728}
729
730void ProcessKDP::DebuggerInitialize(lldb_private::Debugger &debugger) {
731 if (!PluginManager::GetSettingForProcessPlugin(
732 debugger, PluginProperties::GetSettingName())) {
733 const bool is_global_setting = true;
734 PluginManager::CreateSettingForProcessPlugin(
735 debugger, GetGlobalPluginProperties()->GetValueProperties(),
736 ConstString("Properties for the kdp-remote process plug-in."),
737 is_global_setting);
738 }
739}
740
741bool ProcessKDP::StartAsyncThread() {
742 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
743
744 if (log)
745 log->Printf("ProcessKDP::StartAsyncThread ()");
746
747 if (m_async_thread.IsJoinable())
748 return true;
749
750 m_async_thread = ThreadLauncher::LaunchThread(
751 "<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
752 return m_async_thread.IsJoinable();
753}
754
755void ProcessKDP::StopAsyncThread() {
756 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
757
758 if (log)
759 log->Printf("ProcessKDP::StopAsyncThread ()");
760
761 m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
762
763 // Stop the stdio thread
764 if (m_async_thread.IsJoinable())
765 m_async_thread.Join(nullptr);
766}
767
768void *ProcessKDP::AsyncThread(void *arg) {
769 ProcessKDP *process = (ProcessKDP *)arg;
770
771 const lldb::pid_t pid = process->GetID();
772
773 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
774 if (log)
775 log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
776 ") thread starting...",
777 arg, pid);
778
779 ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
780 EventSP event_sp;
781 const uint32_t desired_event_mask =
782 eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
783
784 if (listener_sp->StartListeningForEvents(&process->m_async_broadcaster,
785 desired_event_mask) ==
786 desired_event_mask) {
787 bool done = false;
788 while (!done) {
789 if (log)
790 log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
791 ") listener.WaitForEvent (NULL, event_sp)...",
792 pid);
Pavel Labathfafff0c2016-11-30 11:09:47 +0000793 if (listener_sp->GetEvent(event_sp, llvm::None)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000794 uint32_t event_type = event_sp->GetType();
795 if (log)
796 log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
797 ") Got an event of type: %d...",
798 pid, event_type);
799
800 // When we are running, poll for 1 second to try and get an exception
801 // to indicate the process has stopped. If we don't get one, check to
802 // make sure no one asked us to exit
803 bool is_running = false;
804 DataExtractor exc_reply_packet;
805 do {
806 switch (event_type) {
807 case eBroadcastBitAsyncContinue: {
808 is_running = true;
809 if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds(
810 exc_reply_packet, 1 * USEC_PER_SEC)) {
811 ThreadSP thread_sp(process->GetKernelThread());
812 if (thread_sp) {
813 lldb::RegisterContextSP reg_ctx_sp(
814 thread_sp->GetRegisterContext());
815 if (reg_ctx_sp)
816 reg_ctx_sp->InvalidateAllRegisters();
817 static_cast<ThreadKDP *>(thread_sp.get())
818 ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet);
819 }
820
821 // TODO: parse the stop reply packet
822 is_running = false;
823 process->SetPrivateState(eStateStopped);
824 } else {
825 // Check to see if we are supposed to exit. There is no way to
826 // interrupt a running kernel, so all we can do is wait for an
827 // exception or detach...
Pavel Labathfafff0c2016-11-30 11:09:47 +0000828 if (listener_sp->GetEvent(event_sp,
829 std::chrono::microseconds(0))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000830 // We got an event, go through the loop again
831 event_type = event_sp->GetType();
832 }
Greg Clayton5b882162011-07-21 01:12:01 +0000833 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000834 } break;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000835
Kate Stoneb9c1b512016-09-06 20:57:50 +0000836 case eBroadcastBitAsyncThreadShouldExit:
Greg Claytonf9765ac2011-07-15 03:27:12 +0000837 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838 log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
839 ") got eBroadcastBitAsyncThreadShouldExit...",
840 pid);
841 done = true;
842 is_running = false;
843 break;
Greg Clayton97d5cf02012-09-25 02:40:06 +0000844
Kate Stoneb9c1b512016-09-06 20:57:50 +0000845 default:
846 if (log)
847 log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
848 ") got unknown event 0x%8.8x",
849 pid, event_type);
850 done = true;
851 is_running = false;
852 break;
853 }
854 } while (is_running);
855 } else {
856 if (log)
857 log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
858 ") listener.WaitForEvent (NULL, event_sp) => false",
859 pid);
860 done = true;
861 }
Greg Claytonf9765ac2011-07-15 03:27:12 +0000862 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000863 }
Zachary Turner39de3112014-09-09 20:54:56 +0000864
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865 if (log)
866 log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
867 ") thread exiting...",
868 arg, pid);
869
870 process->m_async_thread.Reset();
871 return NULL;
Greg Claytonf9765ac2011-07-15 03:27:12 +0000872}
873
Kate Stoneb9c1b512016-09-06 20:57:50 +0000874class CommandObjectProcessKDPPacketSend : public CommandObjectParsed {
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000875private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000876 OptionGroupOptions m_option_group;
877 OptionGroupUInt64 m_command_byte;
878 OptionGroupString m_packet_data;
879
880 virtual Options *GetOptions() { return &m_option_group; }
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000881
882public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000883 CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter)
884 : CommandObjectParsed(interpreter, "process plugin packet send",
885 "Send a custom packet through the KDP protocol by "
886 "specifying the command byte and the packet "
887 "payload data. A packet will be sent with a "
888 "correct header and payload, and the raw result "
889 "bytes will be displayed as a string value. ",
890 NULL),
Todd Fialae1cfbc72016-08-11 23:51:28 +0000891 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000892 m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone,
893 "Specify the command byte to use when sending the KDP "
894 "request packet.",
895 0),
896 m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone,
897 "Specify packet payload bytes as a hex ASCII string with "
898 "no spaces or hex prefixes.",
899 NULL) {
900 m_option_group.Append(&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
901 m_option_group.Append(&m_packet_data, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
902 m_option_group.Finalize();
903 }
904
905 ~CommandObjectProcessKDPPacketSend() {}
906
907 bool DoExecute(Args &command, CommandReturnObject &result) {
908 const size_t argc = command.GetArgumentCount();
909 if (argc == 0) {
910 if (!m_command_byte.GetOptionValue().OptionWasSet()) {
911 result.AppendError(
912 "the --command option must be set to a valid command byte");
913 result.SetStatus(eReturnStatusFailed);
914 } else {
915 const uint64_t command_byte =
916 m_command_byte.GetOptionValue().GetUInt64Value(0);
917 if (command_byte > 0 && command_byte <= UINT8_MAX) {
918 ProcessKDP *process =
919 (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
920 if (process) {
921 const StateType state = process->GetState();
922
923 if (StateIsStoppedState(state, true)) {
924 std::vector<uint8_t> payload_bytes;
925 const char *ascii_hex_bytes_cstr =
926 m_packet_data.GetOptionValue().GetCurrentValue();
927 if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) {
928 StringExtractor extractor(ascii_hex_bytes_cstr);
929 const size_t ascii_hex_bytes_cstr_len =
930 extractor.GetStringRef().size();
931 if (ascii_hex_bytes_cstr_len & 1) {
932 result.AppendErrorWithFormat("payload data must contain an "
933 "even number of ASCII hex "
934 "characters: '%s'",
935 ascii_hex_bytes_cstr);
936 result.SetStatus(eReturnStatusFailed);
937 return false;
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000938 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000939 payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);
940 if (extractor.GetHexBytes(payload_bytes, '\xdd') !=
941 payload_bytes.size()) {
942 result.AppendErrorWithFormat("payload data must only contain "
943 "ASCII hex characters (no "
944 "spaces or hex prefixes): '%s'",
945 ascii_hex_bytes_cstr);
946 result.SetStatus(eReturnStatusFailed);
947 return false;
948 }
949 }
Zachary Turner97206d52017-05-12 04:51:55 +0000950 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000951 DataExtractor reply;
952 process->GetCommunication().SendRawRequest(
953 command_byte,
954 payload_bytes.empty() ? NULL : payload_bytes.data(),
955 payload_bytes.size(), reply, error);
956
957 if (error.Success()) {
958 // Copy the binary bytes into a hex ASCII string for the result
959 StreamString packet;
960 packet.PutBytesAsRawHex8(
961 reply.GetDataStart(), reply.GetByteSize(),
962 endian::InlHostByteOrder(), endian::InlHostByteOrder());
Zachary Turnerc1564272016-11-16 21:15:24 +0000963 result.AppendMessage(packet.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000964 result.SetStatus(eReturnStatusSuccessFinishResult);
965 return true;
966 } else {
967 const char *error_cstr = error.AsCString();
968 if (error_cstr && error_cstr[0])
969 result.AppendError(error_cstr);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000970 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000971 result.AppendErrorWithFormat("unknown error 0x%8.8x",
972 error.GetError());
973 result.SetStatus(eReturnStatusFailed);
974 return false;
975 }
976 } else {
977 result.AppendErrorWithFormat("process must be stopped in order "
978 "to send KDP packets, state is %s",
979 StateAsCString(state));
980 result.SetStatus(eReturnStatusFailed);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000981 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000982 } else {
983 result.AppendError("invalid process");
984 result.SetStatus(eReturnStatusFailed);
985 }
986 } else {
987 result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
988 ", valid values are 1 - 255",
989 command_byte);
990 result.SetStatus(eReturnStatusFailed);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000991 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000992 }
993 } else {
994 result.AppendErrorWithFormat("'%s' takes no arguments, only options.",
995 m_cmd_name.c_str());
996 result.SetStatus(eReturnStatusFailed);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000997 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998 return false;
999 }
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001000};
1001
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002class CommandObjectProcessKDPPacket : public CommandObjectMultiword {
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001003private:
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001004public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 CommandObjectProcessKDPPacket(CommandInterpreter &interpreter)
1006 : CommandObjectMultiword(interpreter, "process plugin packet",
1007 "Commands that deal with KDP remote packets.",
1008 NULL) {
1009 LoadSubCommand(
1010 "send",
1011 CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter)));
1012 }
1013
1014 ~CommandObjectProcessKDPPacket() {}
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001015};
1016
Kate Stoneb9c1b512016-09-06 20:57:50 +00001017class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword {
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001018public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001019 CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
1020 : CommandObjectMultiword(
1021 interpreter, "process plugin",
1022 "Commands for operating on a ProcessKDP process.",
1023 "process plugin <subcommand> [<subcommand-options>]") {
1024 LoadSubCommand("packet", CommandObjectSP(new CommandObjectProcessKDPPacket(
1025 interpreter)));
1026 }
1027
1028 ~CommandObjectMultiwordProcessKDP() {}
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001029};
1030
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031CommandObject *ProcessKDP::GetPluginCommandObject() {
1032 if (!m_command_sp)
1033 m_command_sp.reset(new CommandObjectMultiwordProcessKDP(
1034 GetTarget().GetDebugger().GetCommandInterpreter()));
1035 return m_command_sp.get();
Greg Clayton1d19a2f2012-10-19 22:22:57 +00001036}