15ffd83dbSDimitry Andric //===-- GDBRemoteCommunicationServerLLGS.cpp ------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
9fe6060f1SDimitry Andric #include <cerrno>
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "lldb/Host/Config.h"
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include <chrono>
150b57cec5SDimitry Andric #include <cstring>
16fe6060f1SDimitry Andric #include <limits>
170b57cec5SDimitry Andric #include <thread>
180b57cec5SDimitry Andric 
19e8d8bef9SDimitry Andric #include "GDBRemoteCommunicationServerLLGS.h"
200b57cec5SDimitry Andric #include "lldb/Host/ConnectionFileDescriptor.h"
210b57cec5SDimitry Andric #include "lldb/Host/Debug.h"
220b57cec5SDimitry Andric #include "lldb/Host/File.h"
230b57cec5SDimitry Andric #include "lldb/Host/FileAction.h"
240b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h"
250b57cec5SDimitry Andric #include "lldb/Host/Host.h"
260b57cec5SDimitry Andric #include "lldb/Host/HostInfo.h"
270b57cec5SDimitry Andric #include "lldb/Host/PosixApi.h"
280b57cec5SDimitry Andric #include "lldb/Host/common/NativeProcessProtocol.h"
290b57cec5SDimitry Andric #include "lldb/Host/common/NativeRegisterContext.h"
300b57cec5SDimitry Andric #include "lldb/Host/common/NativeThreadProtocol.h"
310b57cec5SDimitry Andric #include "lldb/Target/MemoryRegionInfo.h"
320b57cec5SDimitry Andric #include "lldb/Utility/Args.h"
330b57cec5SDimitry Andric #include "lldb/Utility/DataBuffer.h"
340b57cec5SDimitry Andric #include "lldb/Utility/Endian.h"
35e8d8bef9SDimitry Andric #include "lldb/Utility/GDBRemote.h"
360b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h"
370b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
380b57cec5SDimitry Andric #include "lldb/Utility/RegisterValue.h"
390b57cec5SDimitry Andric #include "lldb/Utility/State.h"
400b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
41e8d8bef9SDimitry Andric #include "lldb/Utility/UnimplementedError.h"
420b57cec5SDimitry Andric #include "lldb/Utility/UriParser.h"
430b57cec5SDimitry Andric #include "llvm/ADT/Triple.h"
449dba64beSDimitry Andric #include "llvm/Support/JSON.h"
450b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric #include "ProcessGDBRemote.h"
480b57cec5SDimitry Andric #include "ProcessGDBRemoteLog.h"
490b57cec5SDimitry Andric #include "lldb/Utility/StringExtractorGDBRemote.h"
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric using namespace lldb;
520b57cec5SDimitry Andric using namespace lldb_private;
530b57cec5SDimitry Andric using namespace lldb_private::process_gdb_remote;
540b57cec5SDimitry Andric using namespace llvm;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric // GDBRemote Errors
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric namespace {
590b57cec5SDimitry Andric enum GDBRemoteServerError {
600b57cec5SDimitry Andric   // Set to the first unused error number in literal form below
610b57cec5SDimitry Andric   eErrorFirst = 29,
620b57cec5SDimitry Andric   eErrorNoProcess = eErrorFirst,
630b57cec5SDimitry Andric   eErrorResume,
640b57cec5SDimitry Andric   eErrorExitStatus
650b57cec5SDimitry Andric };
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric // GDBRemoteCommunicationServerLLGS constructor
690b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(
700b57cec5SDimitry Andric     MainLoop &mainloop, const NativeProcessProtocol::Factory &process_factory)
710b57cec5SDimitry Andric     : GDBRemoteCommunicationServerCommon("gdb-remote.server",
720b57cec5SDimitry Andric                                          "gdb-remote.server.rx_packet"),
730b57cec5SDimitry Andric       m_mainloop(mainloop), m_process_factory(process_factory),
74fe6060f1SDimitry Andric       m_current_process(nullptr), m_continue_process(nullptr),
750b57cec5SDimitry Andric       m_stdio_communication("process.stdio") {
760b57cec5SDimitry Andric   RegisterPacketHandlers();
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
800b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C,
810b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_C);
820b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c,
830b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_c);
840b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D,
850b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_D);
860b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H,
870b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_H);
880b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I,
890b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_I);
900b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
910b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_interrupt,
920b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_interrupt);
930b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
940b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_m,
950b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
960b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M,
970b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_M);
98e8d8bef9SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType__M,
99e8d8bef9SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle__M);
100e8d8bef9SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType__m,
101e8d8bef9SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle__m);
1020b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p,
1030b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_p);
1040b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P,
1050b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_P);
1060b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
1070b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_qC);
1080b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1090b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
1100b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
1110b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1120b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress,
1130b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress);
1140b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1150b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
1160b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
1170b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
118fe6060f1SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
119fe6060f1SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported);
120fe6060f1SDimitry Andric   RegisterMemberFunctionHandler(
121fe6060f1SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
122fe6060f1SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply);
123fe6060f1SDimitry Andric   RegisterMemberFunctionHandler(
1240b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
1250b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo);
1260b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1270b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported,
1280b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported);
1290b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1300b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
1310b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo);
1320b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1330b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qRegisterInfo,
1340b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo);
1350b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1360b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState,
1370b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState);
1380b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1390b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState,
1400b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState);
1410b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1420b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR,
1430b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR);
1440b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1450b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
1460b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir);
1470b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1480b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qsThreadInfo,
1490b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo);
1500b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1510b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo,
1520b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo);
1530b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1540b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_jThreadsInfo,
1550b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo);
1560b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1570b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo,
1580b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo);
1590b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1600b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qXfer,
1610b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qXfer);
1620b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s,
1630b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_s);
1640b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1650b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_stop_reason,
1660b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ?
1670b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1680b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vAttach,
1690b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_vAttach);
1700b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
171e8d8bef9SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vAttachWait,
172e8d8bef9SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_vAttachWait);
173e8d8bef9SDimitry Andric   RegisterMemberFunctionHandler(
174e8d8bef9SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qVAttachOrWaitSupported,
175e8d8bef9SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported);
176e8d8bef9SDimitry Andric   RegisterMemberFunctionHandler(
177e8d8bef9SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vAttachOrWait,
178e8d8bef9SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait);
179e8d8bef9SDimitry Andric   RegisterMemberFunctionHandler(
1800b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vCont,
1810b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_vCont);
1820b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1830b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_vCont_actions,
1840b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions);
1850b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1860b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_x,
1870b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
1880b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z,
1890b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_Z);
1900b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z,
1910b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_z);
1920b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
1930b57cec5SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QPassSignals,
1940b57cec5SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_QPassSignals);
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
197fe6060f1SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupported,
198fe6060f1SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported);
1990b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
200fe6060f1SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStart,
201fe6060f1SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart);
2020b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
203fe6060f1SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStop,
204fe6060f1SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop);
2050b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
206fe6060f1SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetState,
207fe6060f1SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState);
2080b57cec5SDimitry Andric   RegisterMemberFunctionHandler(
209fe6060f1SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetBinaryData,
210fe6060f1SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData);
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g,
2130b57cec5SDimitry Andric                                 &GDBRemoteCommunicationServerLLGS::Handle_g);
2140b57cec5SDimitry Andric 
215fe6060f1SDimitry Andric   RegisterMemberFunctionHandler(
216fe6060f1SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_qMemTags,
217fe6060f1SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_qMemTags);
218fe6060f1SDimitry Andric 
219fe6060f1SDimitry Andric   RegisterMemberFunctionHandler(
220fe6060f1SDimitry Andric       StringExtractorGDBRemote::eServerPacketType_QMemTags,
221fe6060f1SDimitry Andric       &GDBRemoteCommunicationServerLLGS::Handle_QMemTags);
222fe6060f1SDimitry Andric 
2230b57cec5SDimitry Andric   RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
2240b57cec5SDimitry Andric                         [this](StringExtractorGDBRemote packet, Status &error,
2250b57cec5SDimitry Andric                                bool &interrupt, bool &quit) {
2260b57cec5SDimitry Andric                           quit = true;
2270b57cec5SDimitry Andric                           return this->Handle_k(packet);
2280b57cec5SDimitry Andric                         });
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) {
2320b57cec5SDimitry Andric   m_process_launch_info = info;
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
2360b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric   if (!m_process_launch_info.GetArguments().GetArgumentCount())
2390b57cec5SDimitry Andric     return Status("%s: no process command line specified to launch",
2400b57cec5SDimitry Andric                   __FUNCTION__);
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   const bool should_forward_stdio =
2430b57cec5SDimitry Andric       m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr ||
2440b57cec5SDimitry Andric       m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||
2450b57cec5SDimitry Andric       m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr;
2460b57cec5SDimitry Andric   m_process_launch_info.SetLaunchInSeparateProcessGroup(true);
2470b57cec5SDimitry Andric   m_process_launch_info.GetFlags().Set(eLaunchFlagDebug);
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric   if (should_forward_stdio) {
2509dba64beSDimitry Andric     // Temporarily relax the following for Windows until we can take advantage
2519dba64beSDimitry Andric     // of the recently added pty support. This doesn't really affect the use of
2529dba64beSDimitry Andric     // lldb-server on Windows.
2539dba64beSDimitry Andric #if !defined(_WIN32)
2540b57cec5SDimitry Andric     if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection())
2550b57cec5SDimitry Andric       return Status(std::move(Err));
2569dba64beSDimitry Andric #endif
2570b57cec5SDimitry Andric   }
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   {
2600b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
261fe6060f1SDimitry Andric     assert(m_debugged_processes.empty() && "lldb-server creating debugged "
2620b57cec5SDimitry Andric                                            "process but one already exists");
2630b57cec5SDimitry Andric     auto process_or =
2640b57cec5SDimitry Andric         m_process_factory.Launch(m_process_launch_info, *this, m_mainloop);
2650b57cec5SDimitry Andric     if (!process_or)
2660b57cec5SDimitry Andric       return Status(process_or.takeError());
267fe6060f1SDimitry Andric     m_continue_process = m_current_process = process_or->get();
268fe6060f1SDimitry Andric     m_debugged_processes[m_current_process->GetID()] = std::move(*process_or);
2690b57cec5SDimitry Andric   }
2700b57cec5SDimitry Andric 
271fe6060f1SDimitry Andric   SetEnabledExtensions(*m_current_process);
272fe6060f1SDimitry Andric 
2730b57cec5SDimitry Andric   // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as
2740b57cec5SDimitry Andric   // needed. llgs local-process debugging may specify PTY paths, which will
2750b57cec5SDimitry Andric   // make these file actions non-null process launch -i/e/o will also make
2760b57cec5SDimitry Andric   // these file actions non-null nullptr means that the traffic is expected to
2770b57cec5SDimitry Andric   // flow over gdb-remote protocol
2780b57cec5SDimitry Andric   if (should_forward_stdio) {
2790b57cec5SDimitry Andric     // nullptr means it's not redirected to file or pty (in case of LLGS local)
2800b57cec5SDimitry Andric     // at least one of stdio will be transferred pty<->gdb-remote we need to
2810b57cec5SDimitry Andric     // give the pty master handle to this object to read and/or write
2820b57cec5SDimitry Andric     LLDB_LOG(log,
2830b57cec5SDimitry Andric              "pid = {0}: setting up stdout/stderr redirection via $O "
2840b57cec5SDimitry Andric              "gdb-remote commands",
285fe6060f1SDimitry Andric              m_current_process->GetID());
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric     // Setup stdout/stderr mapping from inferior to $O
288fe6060f1SDimitry Andric     auto terminal_fd = m_current_process->GetTerminalFileDescriptor();
2890b57cec5SDimitry Andric     if (terminal_fd >= 0) {
2909dba64beSDimitry Andric       LLDB_LOGF(log,
2919dba64beSDimitry Andric                 "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
2920b57cec5SDimitry Andric                 "inferior STDIO fd to %d",
2930b57cec5SDimitry Andric                 __FUNCTION__, terminal_fd);
2940b57cec5SDimitry Andric       Status status = SetSTDIOFileDescriptor(terminal_fd);
2950b57cec5SDimitry Andric       if (status.Fail())
2960b57cec5SDimitry Andric         return status;
2970b57cec5SDimitry Andric     } else {
2989dba64beSDimitry Andric       LLDB_LOGF(log,
2999dba64beSDimitry Andric                 "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
3000b57cec5SDimitry Andric                 "inferior STDIO since terminal fd reported as %d",
3010b57cec5SDimitry Andric                 __FUNCTION__, terminal_fd);
3020b57cec5SDimitry Andric     }
3030b57cec5SDimitry Andric   } else {
3040b57cec5SDimitry Andric     LLDB_LOG(log,
3050b57cec5SDimitry Andric              "pid = {0} skipping stdout/stderr redirection via $O: inferior "
3060b57cec5SDimitry Andric              "will communicate over client-provided file descriptors",
307fe6060f1SDimitry Andric              m_current_process->GetID());
3080b57cec5SDimitry Andric   }
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   printf("Launched '%s' as process %" PRIu64 "...\n",
3110b57cec5SDimitry Andric          m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
312fe6060f1SDimitry Andric          m_current_process->GetID());
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   return Status();
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
3180b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
3199dba64beSDimitry Andric   LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
3200b57cec5SDimitry Andric             __FUNCTION__, pid);
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   // Before we try to attach, make sure we aren't already monitoring something
3230b57cec5SDimitry Andric   // else.
324fe6060f1SDimitry Andric   if (!m_debugged_processes.empty())
3250b57cec5SDimitry Andric     return Status("cannot attach to process %" PRIu64
3260b57cec5SDimitry Andric                   " when another process with pid %" PRIu64
3270b57cec5SDimitry Andric                   " is being debugged.",
328fe6060f1SDimitry Andric                   pid, m_current_process->GetID());
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   // Try to attach.
3310b57cec5SDimitry Andric   auto process_or = m_process_factory.Attach(pid, *this, m_mainloop);
3320b57cec5SDimitry Andric   if (!process_or) {
3330b57cec5SDimitry Andric     Status status(process_or.takeError());
3340b57cec5SDimitry Andric     llvm::errs() << llvm::formatv("failed to attach to process {0}: {1}", pid,
3350b57cec5SDimitry Andric                                   status);
3360b57cec5SDimitry Andric     return status;
3370b57cec5SDimitry Andric   }
338fe6060f1SDimitry Andric   m_continue_process = m_current_process = process_or->get();
339fe6060f1SDimitry Andric   m_debugged_processes[m_current_process->GetID()] = std::move(*process_or);
340fe6060f1SDimitry Andric   SetEnabledExtensions(*m_current_process);
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   // Setup stdout/stderr mapping from inferior.
343fe6060f1SDimitry Andric   auto terminal_fd = m_current_process->GetTerminalFileDescriptor();
3440b57cec5SDimitry Andric   if (terminal_fd >= 0) {
3459dba64beSDimitry Andric     LLDB_LOGF(log,
3469dba64beSDimitry Andric               "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
3470b57cec5SDimitry Andric               "inferior STDIO fd to %d",
3480b57cec5SDimitry Andric               __FUNCTION__, terminal_fd);
3490b57cec5SDimitry Andric     Status status = SetSTDIOFileDescriptor(terminal_fd);
3500b57cec5SDimitry Andric     if (status.Fail())
3510b57cec5SDimitry Andric       return status;
3520b57cec5SDimitry Andric   } else {
3539dba64beSDimitry Andric     LLDB_LOGF(log,
3549dba64beSDimitry Andric               "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
3550b57cec5SDimitry Andric               "inferior STDIO since terminal fd reported as %d",
3560b57cec5SDimitry Andric               __FUNCTION__, terminal_fd);
3570b57cec5SDimitry Andric   }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   printf("Attached to process %" PRIu64 "...\n", pid);
3600b57cec5SDimitry Andric   return Status();
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric 
363e8d8bef9SDimitry Andric Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess(
364e8d8bef9SDimitry Andric     llvm::StringRef process_name, bool include_existing) {
365e8d8bef9SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
366e8d8bef9SDimitry Andric 
367e8d8bef9SDimitry Andric   std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1);
368e8d8bef9SDimitry Andric 
369e8d8bef9SDimitry Andric   // Create the matcher used to search the process list.
370e8d8bef9SDimitry Andric   ProcessInstanceInfoList exclusion_list;
371e8d8bef9SDimitry Andric   ProcessInstanceInfoMatch match_info;
372e8d8bef9SDimitry Andric   match_info.GetProcessInfo().GetExecutableFile().SetFile(
373e8d8bef9SDimitry Andric       process_name, llvm::sys::path::Style::native);
374e8d8bef9SDimitry Andric   match_info.SetNameMatchType(NameMatch::Equals);
375e8d8bef9SDimitry Andric 
376e8d8bef9SDimitry Andric   if (include_existing) {
377e8d8bef9SDimitry Andric     LLDB_LOG(log, "including existing processes in search");
378e8d8bef9SDimitry Andric   } else {
379e8d8bef9SDimitry Andric     // Create the excluded process list before polling begins.
380e8d8bef9SDimitry Andric     Host::FindProcesses(match_info, exclusion_list);
381e8d8bef9SDimitry Andric     LLDB_LOG(log, "placed '{0}' processes in the exclusion list.",
382e8d8bef9SDimitry Andric              exclusion_list.size());
383e8d8bef9SDimitry Andric   }
384e8d8bef9SDimitry Andric 
385e8d8bef9SDimitry Andric   LLDB_LOG(log, "waiting for '{0}' to appear", process_name);
386e8d8bef9SDimitry Andric 
387e8d8bef9SDimitry Andric   auto is_in_exclusion_list =
388e8d8bef9SDimitry Andric       [&exclusion_list](const ProcessInstanceInfo &info) {
389e8d8bef9SDimitry Andric         for (auto &excluded : exclusion_list) {
390e8d8bef9SDimitry Andric           if (excluded.GetProcessID() == info.GetProcessID())
391e8d8bef9SDimitry Andric             return true;
392e8d8bef9SDimitry Andric         }
393e8d8bef9SDimitry Andric         return false;
394e8d8bef9SDimitry Andric       };
395e8d8bef9SDimitry Andric 
396e8d8bef9SDimitry Andric   ProcessInstanceInfoList loop_process_list;
397e8d8bef9SDimitry Andric   while (true) {
398e8d8bef9SDimitry Andric     loop_process_list.clear();
399e8d8bef9SDimitry Andric     if (Host::FindProcesses(match_info, loop_process_list)) {
400e8d8bef9SDimitry Andric       // Remove all the elements that are in the exclusion list.
401e8d8bef9SDimitry Andric       llvm::erase_if(loop_process_list, is_in_exclusion_list);
402e8d8bef9SDimitry Andric 
403e8d8bef9SDimitry Andric       // One match! We found the desired process.
404e8d8bef9SDimitry Andric       if (loop_process_list.size() == 1) {
405e8d8bef9SDimitry Andric         auto matching_process_pid = loop_process_list[0].GetProcessID();
406e8d8bef9SDimitry Andric         LLDB_LOG(log, "found pid {0}", matching_process_pid);
407e8d8bef9SDimitry Andric         return AttachToProcess(matching_process_pid);
408e8d8bef9SDimitry Andric       }
409e8d8bef9SDimitry Andric 
410e8d8bef9SDimitry Andric       // Multiple matches! Return an error reporting the PIDs we found.
411e8d8bef9SDimitry Andric       if (loop_process_list.size() > 1) {
412e8d8bef9SDimitry Andric         StreamString error_stream;
413e8d8bef9SDimitry Andric         error_stream.Format(
414e8d8bef9SDimitry Andric             "Multiple executables with name: '{0}' found. Pids: ",
415e8d8bef9SDimitry Andric             process_name);
416e8d8bef9SDimitry Andric         for (size_t i = 0; i < loop_process_list.size() - 1; ++i) {
417e8d8bef9SDimitry Andric           error_stream.Format("{0}, ", loop_process_list[i].GetProcessID());
418e8d8bef9SDimitry Andric         }
419e8d8bef9SDimitry Andric         error_stream.Format("{0}.", loop_process_list.back().GetProcessID());
420e8d8bef9SDimitry Andric 
421e8d8bef9SDimitry Andric         Status error;
422e8d8bef9SDimitry Andric         error.SetErrorString(error_stream.GetString());
423e8d8bef9SDimitry Andric         return error;
424e8d8bef9SDimitry Andric       }
425e8d8bef9SDimitry Andric     }
426e8d8bef9SDimitry Andric     // No matches, we have not found the process. Sleep until next poll.
427e8d8bef9SDimitry Andric     LLDB_LOG(log, "sleep {0} seconds", polling_interval);
428e8d8bef9SDimitry Andric     std::this_thread::sleep_for(polling_interval);
429e8d8bef9SDimitry Andric   }
430e8d8bef9SDimitry Andric }
431e8d8bef9SDimitry Andric 
4320b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
4330b57cec5SDimitry Andric     NativeProcessProtocol *process) {
4340b57cec5SDimitry Andric   assert(process && "process cannot be NULL");
4350b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
4360b57cec5SDimitry Andric   if (log) {
4379dba64beSDimitry Andric     LLDB_LOGF(log,
4389dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s called with "
4390b57cec5SDimitry Andric               "NativeProcessProtocol pid %" PRIu64 ", current state: %s",
4400b57cec5SDimitry Andric               __FUNCTION__, process->GetID(),
4410b57cec5SDimitry Andric               StateAsCString(process->GetState()));
4420b57cec5SDimitry Andric   }
4430b57cec5SDimitry Andric }
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
4460b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendWResponse(
4470b57cec5SDimitry Andric     NativeProcessProtocol *process) {
4480b57cec5SDimitry Andric   assert(process && "process cannot be NULL");
4490b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   // send W notification
4520b57cec5SDimitry Andric   auto wait_status = process->GetExitStatus();
4530b57cec5SDimitry Andric   if (!wait_status) {
4540b57cec5SDimitry Andric     LLDB_LOG(log, "pid = {0}, failed to retrieve process exit status",
4550b57cec5SDimitry Andric              process->GetID());
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric     StreamGDBRemote response;
4580b57cec5SDimitry Andric     response.PutChar('E');
4590b57cec5SDimitry Andric     response.PutHex8(GDBRemoteServerError::eErrorExitStatus);
4600b57cec5SDimitry Andric     return SendPacketNoLock(response.GetString());
4610b57cec5SDimitry Andric   }
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric   LLDB_LOG(log, "pid = {0}, returning exit type {1}", process->GetID(),
4640b57cec5SDimitry Andric            *wait_status);
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric   StreamGDBRemote response;
4670b57cec5SDimitry Andric   response.Format("{0:g}", *wait_status);
4680b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
4690b57cec5SDimitry Andric }
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric static void AppendHexValue(StreamString &response, const uint8_t *buf,
4720b57cec5SDimitry Andric                            uint32_t buf_size, bool swap) {
4730b57cec5SDimitry Andric   int64_t i;
4740b57cec5SDimitry Andric   if (swap) {
4750b57cec5SDimitry Andric     for (i = buf_size - 1; i >= 0; i--)
4760b57cec5SDimitry Andric       response.PutHex8(buf[i]);
4770b57cec5SDimitry Andric   } else {
4780b57cec5SDimitry Andric     for (i = 0; i < buf_size; i++)
4790b57cec5SDimitry Andric       response.PutHex8(buf[i]);
4800b57cec5SDimitry Andric   }
4810b57cec5SDimitry Andric }
4820b57cec5SDimitry Andric 
4835ffd83dbSDimitry Andric static llvm::StringRef GetEncodingNameOrEmpty(const RegisterInfo &reg_info) {
4845ffd83dbSDimitry Andric   switch (reg_info.encoding) {
4855ffd83dbSDimitry Andric   case eEncodingUint:
4865ffd83dbSDimitry Andric     return "uint";
4875ffd83dbSDimitry Andric   case eEncodingSint:
4885ffd83dbSDimitry Andric     return "sint";
4895ffd83dbSDimitry Andric   case eEncodingIEEE754:
4905ffd83dbSDimitry Andric     return "ieee754";
4915ffd83dbSDimitry Andric   case eEncodingVector:
4925ffd83dbSDimitry Andric     return "vector";
4935ffd83dbSDimitry Andric   default:
4945ffd83dbSDimitry Andric     return "";
4955ffd83dbSDimitry Andric   }
4965ffd83dbSDimitry Andric }
4975ffd83dbSDimitry Andric 
4985ffd83dbSDimitry Andric static llvm::StringRef GetFormatNameOrEmpty(const RegisterInfo &reg_info) {
4995ffd83dbSDimitry Andric   switch (reg_info.format) {
5005ffd83dbSDimitry Andric   case eFormatBinary:
5015ffd83dbSDimitry Andric     return "binary";
5025ffd83dbSDimitry Andric   case eFormatDecimal:
5035ffd83dbSDimitry Andric     return "decimal";
5045ffd83dbSDimitry Andric   case eFormatHex:
5055ffd83dbSDimitry Andric     return "hex";
5065ffd83dbSDimitry Andric   case eFormatFloat:
5075ffd83dbSDimitry Andric     return "float";
5085ffd83dbSDimitry Andric   case eFormatVectorOfSInt8:
5095ffd83dbSDimitry Andric     return "vector-sint8";
5105ffd83dbSDimitry Andric   case eFormatVectorOfUInt8:
5115ffd83dbSDimitry Andric     return "vector-uint8";
5125ffd83dbSDimitry Andric   case eFormatVectorOfSInt16:
5135ffd83dbSDimitry Andric     return "vector-sint16";
5145ffd83dbSDimitry Andric   case eFormatVectorOfUInt16:
5155ffd83dbSDimitry Andric     return "vector-uint16";
5165ffd83dbSDimitry Andric   case eFormatVectorOfSInt32:
5175ffd83dbSDimitry Andric     return "vector-sint32";
5185ffd83dbSDimitry Andric   case eFormatVectorOfUInt32:
5195ffd83dbSDimitry Andric     return "vector-uint32";
5205ffd83dbSDimitry Andric   case eFormatVectorOfFloat32:
5215ffd83dbSDimitry Andric     return "vector-float32";
5225ffd83dbSDimitry Andric   case eFormatVectorOfUInt64:
5235ffd83dbSDimitry Andric     return "vector-uint64";
5245ffd83dbSDimitry Andric   case eFormatVectorOfUInt128:
5255ffd83dbSDimitry Andric     return "vector-uint128";
5265ffd83dbSDimitry Andric   default:
5275ffd83dbSDimitry Andric     return "";
5285ffd83dbSDimitry Andric   };
5295ffd83dbSDimitry Andric }
5305ffd83dbSDimitry Andric 
5315ffd83dbSDimitry Andric static llvm::StringRef GetKindGenericOrEmpty(const RegisterInfo &reg_info) {
5325ffd83dbSDimitry Andric   switch (reg_info.kinds[RegisterKind::eRegisterKindGeneric]) {
5335ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_PC:
5345ffd83dbSDimitry Andric     return "pc";
5355ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_SP:
5365ffd83dbSDimitry Andric     return "sp";
5375ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_FP:
5385ffd83dbSDimitry Andric     return "fp";
5395ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_RA:
5405ffd83dbSDimitry Andric     return "ra";
5415ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_FLAGS:
5425ffd83dbSDimitry Andric     return "flags";
5435ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_ARG1:
5445ffd83dbSDimitry Andric     return "arg1";
5455ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_ARG2:
5465ffd83dbSDimitry Andric     return "arg2";
5475ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_ARG3:
5485ffd83dbSDimitry Andric     return "arg3";
5495ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_ARG4:
5505ffd83dbSDimitry Andric     return "arg4";
5515ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_ARG5:
5525ffd83dbSDimitry Andric     return "arg5";
5535ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_ARG6:
5545ffd83dbSDimitry Andric     return "arg6";
5555ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_ARG7:
5565ffd83dbSDimitry Andric     return "arg7";
5575ffd83dbSDimitry Andric   case LLDB_REGNUM_GENERIC_ARG8:
5585ffd83dbSDimitry Andric     return "arg8";
5595ffd83dbSDimitry Andric   default:
5605ffd83dbSDimitry Andric     return "";
5615ffd83dbSDimitry Andric   }
5625ffd83dbSDimitry Andric }
5635ffd83dbSDimitry Andric 
5645ffd83dbSDimitry Andric static void CollectRegNums(const uint32_t *reg_num, StreamString &response,
5655ffd83dbSDimitry Andric                            bool usehex) {
5665ffd83dbSDimitry Andric   for (int i = 0; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
5675ffd83dbSDimitry Andric     if (i > 0)
5685ffd83dbSDimitry Andric       response.PutChar(',');
5695ffd83dbSDimitry Andric     if (usehex)
5705ffd83dbSDimitry Andric       response.Printf("%" PRIx32, *reg_num);
5715ffd83dbSDimitry Andric     else
5725ffd83dbSDimitry Andric       response.Printf("%" PRIu32, *reg_num);
5735ffd83dbSDimitry Andric   }
5745ffd83dbSDimitry Andric }
5755ffd83dbSDimitry Andric 
5760b57cec5SDimitry Andric static void WriteRegisterValueInHexFixedWidth(
5770b57cec5SDimitry Andric     StreamString &response, NativeRegisterContext &reg_ctx,
5780b57cec5SDimitry Andric     const RegisterInfo &reg_info, const RegisterValue *reg_value_p,
5790b57cec5SDimitry Andric     lldb::ByteOrder byte_order) {
5800b57cec5SDimitry Andric   RegisterValue reg_value;
5810b57cec5SDimitry Andric   if (!reg_value_p) {
5820b57cec5SDimitry Andric     Status error = reg_ctx.ReadRegister(&reg_info, reg_value);
5830b57cec5SDimitry Andric     if (error.Success())
5840b57cec5SDimitry Andric       reg_value_p = &reg_value;
5850b57cec5SDimitry Andric     // else log.
5860b57cec5SDimitry Andric   }
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric   if (reg_value_p) {
5890b57cec5SDimitry Andric     AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(),
5900b57cec5SDimitry Andric                    reg_value_p->GetByteSize(),
5910b57cec5SDimitry Andric                    byte_order == lldb::eByteOrderLittle);
5920b57cec5SDimitry Andric   } else {
5930b57cec5SDimitry Andric     // Zero-out any unreadable values.
5940b57cec5SDimitry Andric     if (reg_info.byte_size > 0) {
5950b57cec5SDimitry Andric       std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0');
5960b57cec5SDimitry Andric       AppendHexValue(response, zeros.data(), zeros.size(), false);
5970b57cec5SDimitry Andric     }
5980b57cec5SDimitry Andric   }
5990b57cec5SDimitry Andric }
6000b57cec5SDimitry Andric 
601e8d8bef9SDimitry Andric static llvm::Optional<json::Object>
6029dba64beSDimitry Andric GetRegistersAsJSON(NativeThreadProtocol &thread) {
6030b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
6040b57cec5SDimitry Andric 
6050b57cec5SDimitry Andric   NativeRegisterContext& reg_ctx = thread.GetRegisterContext();
6060b57cec5SDimitry Andric 
6079dba64beSDimitry Andric   json::Object register_object;
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric #ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
610e8d8bef9SDimitry Andric   const auto expedited_regs =
611e8d8bef9SDimitry Andric       reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full);
6120b57cec5SDimitry Andric #else
613e8d8bef9SDimitry Andric   const auto expedited_regs =
614e8d8bef9SDimitry Andric       reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Minimal);
6150b57cec5SDimitry Andric #endif
616e8d8bef9SDimitry Andric   if (expedited_regs.empty())
617e8d8bef9SDimitry Andric     return llvm::None;
6180b57cec5SDimitry Andric 
619e8d8bef9SDimitry Andric   for (auto &reg_num : expedited_regs) {
6200b57cec5SDimitry Andric     const RegisterInfo *const reg_info_p =
6210b57cec5SDimitry Andric         reg_ctx.GetRegisterInfoAtIndex(reg_num);
6220b57cec5SDimitry Andric     if (reg_info_p == nullptr) {
6239dba64beSDimitry Andric       LLDB_LOGF(log,
6240b57cec5SDimitry Andric                 "%s failed to get register info for register index %" PRIu32,
6250b57cec5SDimitry Andric                 __FUNCTION__, reg_num);
6260b57cec5SDimitry Andric       continue;
6270b57cec5SDimitry Andric     }
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric     if (reg_info_p->value_regs != nullptr)
6300b57cec5SDimitry Andric       continue; // Only expedite registers that are not contained in other
6310b57cec5SDimitry Andric                 // registers.
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric     RegisterValue reg_value;
6340b57cec5SDimitry Andric     Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
6350b57cec5SDimitry Andric     if (error.Fail()) {
6369dba64beSDimitry Andric       LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s",
6370b57cec5SDimitry Andric                 __FUNCTION__,
6380b57cec5SDimitry Andric                 reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
6390b57cec5SDimitry Andric                 reg_num, error.AsCString());
6400b57cec5SDimitry Andric       continue;
6410b57cec5SDimitry Andric     }
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric     StreamString stream;
6440b57cec5SDimitry Andric     WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p,
6450b57cec5SDimitry Andric                                       &reg_value, lldb::eByteOrderBig);
6460b57cec5SDimitry Andric 
6479dba64beSDimitry Andric     register_object.try_emplace(llvm::to_string(reg_num),
6489dba64beSDimitry Andric                                 stream.GetString().str());
6490b57cec5SDimitry Andric   }
6500b57cec5SDimitry Andric 
6519dba64beSDimitry Andric   return register_object;
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric static const char *GetStopReasonString(StopReason stop_reason) {
6550b57cec5SDimitry Andric   switch (stop_reason) {
6560b57cec5SDimitry Andric   case eStopReasonTrace:
6570b57cec5SDimitry Andric     return "trace";
6580b57cec5SDimitry Andric   case eStopReasonBreakpoint:
6590b57cec5SDimitry Andric     return "breakpoint";
6600b57cec5SDimitry Andric   case eStopReasonWatchpoint:
6610b57cec5SDimitry Andric     return "watchpoint";
6620b57cec5SDimitry Andric   case eStopReasonSignal:
6630b57cec5SDimitry Andric     return "signal";
6640b57cec5SDimitry Andric   case eStopReasonException:
6650b57cec5SDimitry Andric     return "exception";
6660b57cec5SDimitry Andric   case eStopReasonExec:
6670b57cec5SDimitry Andric     return "exec";
668fe6060f1SDimitry Andric   case eStopReasonProcessorTrace:
669fe6060f1SDimitry Andric     return "processor trace";
670fe6060f1SDimitry Andric   case eStopReasonFork:
671fe6060f1SDimitry Andric     return "fork";
672fe6060f1SDimitry Andric   case eStopReasonVFork:
673fe6060f1SDimitry Andric     return "vfork";
674fe6060f1SDimitry Andric   case eStopReasonVForkDone:
675fe6060f1SDimitry Andric     return "vforkdone";
6760b57cec5SDimitry Andric   case eStopReasonInstrumentation:
6770b57cec5SDimitry Andric   case eStopReasonInvalid:
6780b57cec5SDimitry Andric   case eStopReasonPlanComplete:
6790b57cec5SDimitry Andric   case eStopReasonThreadExiting:
6800b57cec5SDimitry Andric   case eStopReasonNone:
6810b57cec5SDimitry Andric     break; // ignored
6820b57cec5SDimitry Andric   }
6830b57cec5SDimitry Andric   return nullptr;
6840b57cec5SDimitry Andric }
6850b57cec5SDimitry Andric 
6869dba64beSDimitry Andric static llvm::Expected<json::Array>
6879dba64beSDimitry Andric GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) {
6880b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
6890b57cec5SDimitry Andric 
6909dba64beSDimitry Andric   json::Array threads_array;
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric   // Ensure we can get info on the given thread.
6930b57cec5SDimitry Andric   uint32_t thread_idx = 0;
6940b57cec5SDimitry Andric   for (NativeThreadProtocol *thread;
6950b57cec5SDimitry Andric        (thread = process.GetThreadAtIndex(thread_idx)) != nullptr;
6960b57cec5SDimitry Andric        ++thread_idx) {
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric     lldb::tid_t tid = thread->GetID();
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric     // Grab the reason this thread stopped.
7010b57cec5SDimitry Andric     struct ThreadStopInfo tid_stop_info;
7020b57cec5SDimitry Andric     std::string description;
7030b57cec5SDimitry Andric     if (!thread->GetStopReason(tid_stop_info, description))
7049dba64beSDimitry Andric       return llvm::make_error<llvm::StringError>(
7059dba64beSDimitry Andric           "failed to get stop reason", llvm::inconvertibleErrorCode());
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric     const int signum = tid_stop_info.details.signal.signo;
7080b57cec5SDimitry Andric     if (log) {
7099dba64beSDimitry Andric       LLDB_LOGF(log,
7109dba64beSDimitry Andric                 "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
7110b57cec5SDimitry Andric                 " tid %" PRIu64
7120b57cec5SDimitry Andric                 " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
7130b57cec5SDimitry Andric                 __FUNCTION__, process.GetID(), tid, signum,
7140b57cec5SDimitry Andric                 tid_stop_info.reason, tid_stop_info.details.exception.type);
7150b57cec5SDimitry Andric     }
7160b57cec5SDimitry Andric 
7179dba64beSDimitry Andric     json::Object thread_obj;
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric     if (!abridged) {
720e8d8bef9SDimitry Andric       if (llvm::Optional<json::Object> registers = GetRegistersAsJSON(*thread))
7219dba64beSDimitry Andric         thread_obj.try_emplace("registers", std::move(*registers));
7220b57cec5SDimitry Andric     }
7230b57cec5SDimitry Andric 
7249dba64beSDimitry Andric     thread_obj.try_emplace("tid", static_cast<int64_t>(tid));
7259dba64beSDimitry Andric 
7260b57cec5SDimitry Andric     if (signum != 0)
7279dba64beSDimitry Andric       thread_obj.try_emplace("signal", signum);
7280b57cec5SDimitry Andric 
7290b57cec5SDimitry Andric     const std::string thread_name = thread->GetName();
7300b57cec5SDimitry Andric     if (!thread_name.empty())
7319dba64beSDimitry Andric       thread_obj.try_emplace("name", thread_name);
7320b57cec5SDimitry Andric 
7339dba64beSDimitry Andric     const char *stop_reason = GetStopReasonString(tid_stop_info.reason);
7349dba64beSDimitry Andric     if (stop_reason)
7359dba64beSDimitry Andric       thread_obj.try_emplace("reason", stop_reason);
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric     if (!description.empty())
7389dba64beSDimitry Andric       thread_obj.try_emplace("description", description);
7390b57cec5SDimitry Andric 
7400b57cec5SDimitry Andric     if ((tid_stop_info.reason == eStopReasonException) &&
7410b57cec5SDimitry Andric         tid_stop_info.details.exception.type) {
7429dba64beSDimitry Andric       thread_obj.try_emplace(
7439dba64beSDimitry Andric           "metype", static_cast<int64_t>(tid_stop_info.details.exception.type));
7440b57cec5SDimitry Andric 
7459dba64beSDimitry Andric       json::Array medata_array;
7460b57cec5SDimitry Andric       for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count;
7470b57cec5SDimitry Andric            ++i) {
7489dba64beSDimitry Andric         medata_array.push_back(
7499dba64beSDimitry Andric             static_cast<int64_t>(tid_stop_info.details.exception.data[i]));
7500b57cec5SDimitry Andric       }
7519dba64beSDimitry Andric       thread_obj.try_emplace("medata", std::move(medata_array));
7520b57cec5SDimitry Andric     }
7539dba64beSDimitry Andric     threads_array.push_back(std::move(thread_obj));
7540b57cec5SDimitry Andric   }
7559dba64beSDimitry Andric   return threads_array;
7560b57cec5SDimitry Andric }
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
7590b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
7600b57cec5SDimitry Andric     lldb::tid_t tid) {
7610b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
7620b57cec5SDimitry Andric 
7630b57cec5SDimitry Andric   // Ensure we have a debugged process.
764fe6060f1SDimitry Andric   if (!m_current_process ||
765fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
7660b57cec5SDimitry Andric     return SendErrorResponse(50);
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric   LLDB_LOG(log, "preparing packet for pid {0} tid {1}",
769fe6060f1SDimitry Andric            m_current_process->GetID(), tid);
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric   // Ensure we can get info on the given thread.
772fe6060f1SDimitry Andric   NativeThreadProtocol *thread = m_current_process->GetThreadByID(tid);
7730b57cec5SDimitry Andric   if (!thread)
7740b57cec5SDimitry Andric     return SendErrorResponse(51);
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric   // Grab the reason this thread stopped.
7770b57cec5SDimitry Andric   struct ThreadStopInfo tid_stop_info;
7780b57cec5SDimitry Andric   std::string description;
7790b57cec5SDimitry Andric   if (!thread->GetStopReason(tid_stop_info, description))
7800b57cec5SDimitry Andric     return SendErrorResponse(52);
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   // FIXME implement register handling for exec'd inferiors.
7830b57cec5SDimitry Andric   // if (tid_stop_info.reason == eStopReasonExec) {
7840b57cec5SDimitry Andric   //     const bool force = true;
7850b57cec5SDimitry Andric   //     InitializeRegisters(force);
7860b57cec5SDimitry Andric   // }
7870b57cec5SDimitry Andric 
7880b57cec5SDimitry Andric   StreamString response;
7890b57cec5SDimitry Andric   // Output the T packet with the thread
7900b57cec5SDimitry Andric   response.PutChar('T');
7910b57cec5SDimitry Andric   int signum = tid_stop_info.details.signal.signo;
7920b57cec5SDimitry Andric   LLDB_LOG(
7930b57cec5SDimitry Andric       log,
7940b57cec5SDimitry Andric       "pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}",
795fe6060f1SDimitry Andric       m_current_process->GetID(), tid, signum, int(tid_stop_info.reason),
7960b57cec5SDimitry Andric       tid_stop_info.details.exception.type);
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric   // Print the signal number.
7990b57cec5SDimitry Andric   response.PutHex8(signum & 0xff);
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric   // Include the tid.
8020b57cec5SDimitry Andric   response.Printf("thread:%" PRIx64 ";", tid);
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric   // Include the thread name if there is one.
8050b57cec5SDimitry Andric   const std::string thread_name = thread->GetName();
8060b57cec5SDimitry Andric   if (!thread_name.empty()) {
8070b57cec5SDimitry Andric     size_t thread_name_len = thread_name.length();
8080b57cec5SDimitry Andric 
8090b57cec5SDimitry Andric     if (::strcspn(thread_name.c_str(), "$#+-;:") == thread_name_len) {
8100b57cec5SDimitry Andric       response.PutCString("name:");
8110b57cec5SDimitry Andric       response.PutCString(thread_name);
8120b57cec5SDimitry Andric     } else {
8130b57cec5SDimitry Andric       // The thread name contains special chars, send as hex bytes.
8140b57cec5SDimitry Andric       response.PutCString("hexname:");
8150b57cec5SDimitry Andric       response.PutStringAsRawHex8(thread_name);
8160b57cec5SDimitry Andric     }
8170b57cec5SDimitry Andric     response.PutChar(';');
8180b57cec5SDimitry Andric   }
8190b57cec5SDimitry Andric 
8200b57cec5SDimitry Andric   // If a 'QListThreadsInStopReply' was sent to enable this feature, we will
8210b57cec5SDimitry Andric   // send all thread IDs back in the "threads" key whose value is a list of hex
8220b57cec5SDimitry Andric   // thread IDs separated by commas:
8230b57cec5SDimitry Andric   //  "threads:10a,10b,10c;"
8240b57cec5SDimitry Andric   // This will save the debugger from having to send a pair of qfThreadInfo and
8250b57cec5SDimitry Andric   // qsThreadInfo packets, but it also might take a lot of room in the stop
8260b57cec5SDimitry Andric   // reply packet, so it must be enabled only on systems where there are no
8270b57cec5SDimitry Andric   // limits on packet lengths.
8280b57cec5SDimitry Andric   if (m_list_threads_in_stop_reply) {
8290b57cec5SDimitry Andric     response.PutCString("threads:");
8300b57cec5SDimitry Andric 
8310b57cec5SDimitry Andric     uint32_t thread_index = 0;
8320b57cec5SDimitry Andric     NativeThreadProtocol *listed_thread;
833fe6060f1SDimitry Andric     for (listed_thread = m_current_process->GetThreadAtIndex(thread_index);
8340b57cec5SDimitry Andric          listed_thread; ++thread_index,
835fe6060f1SDimitry Andric         listed_thread = m_current_process->GetThreadAtIndex(thread_index)) {
8360b57cec5SDimitry Andric       if (thread_index > 0)
8370b57cec5SDimitry Andric         response.PutChar(',');
8380b57cec5SDimitry Andric       response.Printf("%" PRIx64, listed_thread->GetID());
8390b57cec5SDimitry Andric     }
8400b57cec5SDimitry Andric     response.PutChar(';');
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric     // Include JSON info that describes the stop reason for any threads that
8430b57cec5SDimitry Andric     // actually have stop reasons. We use the new "jstopinfo" key whose values
8440b57cec5SDimitry Andric     // is hex ascii JSON that contains the thread IDs thread stop info only for
8450b57cec5SDimitry Andric     // threads that have stop reasons. Only send this if we have more than one
8460b57cec5SDimitry Andric     // thread otherwise this packet has all the info it needs.
8479dba64beSDimitry Andric     if (thread_index > 1) {
8480b57cec5SDimitry Andric       const bool threads_with_valid_stop_info_only = true;
8499dba64beSDimitry Andric       llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo(
850fe6060f1SDimitry Andric           *m_current_process, threads_with_valid_stop_info_only);
8519dba64beSDimitry Andric       if (threads_info) {
8520b57cec5SDimitry Andric         response.PutCString("jstopinfo:");
8530b57cec5SDimitry Andric         StreamString unescaped_response;
8549dba64beSDimitry Andric         unescaped_response.AsRawOstream() << std::move(*threads_info);
8550b57cec5SDimitry Andric         response.PutStringAsRawHex8(unescaped_response.GetData());
8560b57cec5SDimitry Andric         response.PutChar(';');
8579dba64beSDimitry Andric       } else {
858480093f4SDimitry Andric         LLDB_LOG_ERROR(log, threads_info.takeError(),
859480093f4SDimitry Andric                        "failed to prepare a jstopinfo field for pid {1}: {0}",
860fe6060f1SDimitry Andric                        m_current_process->GetID());
8619dba64beSDimitry Andric       }
8620b57cec5SDimitry Andric     }
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric     uint32_t i = 0;
8650b57cec5SDimitry Andric     response.PutCString("thread-pcs");
8660b57cec5SDimitry Andric     char delimiter = ':';
8670b57cec5SDimitry Andric     for (NativeThreadProtocol *thread;
868fe6060f1SDimitry Andric          (thread = m_current_process->GetThreadAtIndex(i)) != nullptr; ++i) {
8690b57cec5SDimitry Andric       NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
8700b57cec5SDimitry Andric 
8710b57cec5SDimitry Andric       uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber(
8720b57cec5SDimitry Andric           eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
8730b57cec5SDimitry Andric       const RegisterInfo *const reg_info_p =
8740b57cec5SDimitry Andric           reg_ctx.GetRegisterInfoAtIndex(reg_to_read);
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric       RegisterValue reg_value;
8770b57cec5SDimitry Andric       Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
8780b57cec5SDimitry Andric       if (error.Fail()) {
8799dba64beSDimitry Andric         LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s",
8800b57cec5SDimitry Andric                   __FUNCTION__,
8819dba64beSDimitry Andric                   reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
8820b57cec5SDimitry Andric                   reg_to_read, error.AsCString());
8830b57cec5SDimitry Andric         continue;
8840b57cec5SDimitry Andric       }
8850b57cec5SDimitry Andric 
8860b57cec5SDimitry Andric       response.PutChar(delimiter);
8870b57cec5SDimitry Andric       delimiter = ',';
8880b57cec5SDimitry Andric       WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
8890b57cec5SDimitry Andric                                         &reg_value, endian::InlHostByteOrder());
8900b57cec5SDimitry Andric     }
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric     response.PutChar(';');
8930b57cec5SDimitry Andric   }
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric   //
8960b57cec5SDimitry Andric   // Expedite registers.
8970b57cec5SDimitry Andric   //
8980b57cec5SDimitry Andric 
8990b57cec5SDimitry Andric   // Grab the register context.
9000b57cec5SDimitry Andric   NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
901e8d8bef9SDimitry Andric   const auto expedited_regs =
902e8d8bef9SDimitry Andric       reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full);
9030b57cec5SDimitry Andric 
904e8d8bef9SDimitry Andric   for (auto &reg_num : expedited_regs) {
9050b57cec5SDimitry Andric     const RegisterInfo *const reg_info_p =
906e8d8bef9SDimitry Andric         reg_ctx.GetRegisterInfoAtIndex(reg_num);
9070b57cec5SDimitry Andric     // Only expediate registers that are not contained in other registers.
908e8d8bef9SDimitry Andric     if (reg_info_p != nullptr && reg_info_p->value_regs == nullptr) {
9090b57cec5SDimitry Andric       RegisterValue reg_value;
9100b57cec5SDimitry Andric       Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
9110b57cec5SDimitry Andric       if (error.Success()) {
912e8d8bef9SDimitry Andric         response.Printf("%.02x:", reg_num);
9130b57cec5SDimitry Andric         WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
9140b57cec5SDimitry Andric                                           &reg_value, lldb::eByteOrderBig);
9150b57cec5SDimitry Andric         response.PutChar(';');
9160b57cec5SDimitry Andric       } else {
917e8d8bef9SDimitry Andric         LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed to read "
9180b57cec5SDimitry Andric                        "register '%s' index %" PRIu32 ": %s",
9190b57cec5SDimitry Andric                   __FUNCTION__,
9209dba64beSDimitry Andric                   reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
921e8d8bef9SDimitry Andric                   reg_num, error.AsCString());
9220b57cec5SDimitry Andric       }
9230b57cec5SDimitry Andric     }
9240b57cec5SDimitry Andric   }
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric   const char *reason_str = GetStopReasonString(tid_stop_info.reason);
9270b57cec5SDimitry Andric   if (reason_str != nullptr) {
9280b57cec5SDimitry Andric     response.Printf("reason:%s;", reason_str);
9290b57cec5SDimitry Andric   }
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric   if (!description.empty()) {
9320b57cec5SDimitry Andric     // Description may contains special chars, send as hex bytes.
9330b57cec5SDimitry Andric     response.PutCString("description:");
9340b57cec5SDimitry Andric     response.PutStringAsRawHex8(description);
9350b57cec5SDimitry Andric     response.PutChar(';');
9360b57cec5SDimitry Andric   } else if ((tid_stop_info.reason == eStopReasonException) &&
9370b57cec5SDimitry Andric              tid_stop_info.details.exception.type) {
9380b57cec5SDimitry Andric     response.PutCString("metype:");
9390b57cec5SDimitry Andric     response.PutHex64(tid_stop_info.details.exception.type);
9400b57cec5SDimitry Andric     response.PutCString(";mecount:");
9410b57cec5SDimitry Andric     response.PutHex32(tid_stop_info.details.exception.data_count);
9420b57cec5SDimitry Andric     response.PutChar(';');
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric     for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) {
9450b57cec5SDimitry Andric       response.PutCString("medata:");
9460b57cec5SDimitry Andric       response.PutHex64(tid_stop_info.details.exception.data[i]);
9470b57cec5SDimitry Andric       response.PutChar(';');
9480b57cec5SDimitry Andric     }
9490b57cec5SDimitry Andric   }
9500b57cec5SDimitry Andric 
951fe6060f1SDimitry Andric   // Include child process PID/TID for forks.
952fe6060f1SDimitry Andric   if (tid_stop_info.reason == eStopReasonFork ||
953fe6060f1SDimitry Andric       tid_stop_info.reason == eStopReasonVFork) {
954fe6060f1SDimitry Andric     assert(bool(m_extensions_supported &
955fe6060f1SDimitry Andric                 NativeProcessProtocol::Extension::multiprocess));
956fe6060f1SDimitry Andric     if (tid_stop_info.reason == eStopReasonFork)
957fe6060f1SDimitry Andric       assert(bool(m_extensions_supported &
958fe6060f1SDimitry Andric                   NativeProcessProtocol::Extension::fork));
959fe6060f1SDimitry Andric     if (tid_stop_info.reason == eStopReasonVFork)
960fe6060f1SDimitry Andric       assert(bool(m_extensions_supported &
961fe6060f1SDimitry Andric                   NativeProcessProtocol::Extension::vfork));
962fe6060f1SDimitry Andric     response.Printf("%s:p%" PRIx64 ".%" PRIx64 ";", reason_str,
963fe6060f1SDimitry Andric                     tid_stop_info.details.fork.child_pid,
964fe6060f1SDimitry Andric                     tid_stop_info.details.fork.child_tid);
965fe6060f1SDimitry Andric   }
966fe6060f1SDimitry Andric 
9670b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
9680b57cec5SDimitry Andric }
9690b57cec5SDimitry Andric 
9700b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
9710b57cec5SDimitry Andric     NativeProcessProtocol *process) {
9720b57cec5SDimitry Andric   assert(process && "process cannot be NULL");
9730b57cec5SDimitry Andric 
9740b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
9759dba64beSDimitry Andric   LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
9760b57cec5SDimitry Andric 
9770b57cec5SDimitry Andric   PacketResult result = SendStopReasonForState(StateType::eStateExited);
9780b57cec5SDimitry Andric   if (result != PacketResult::Success) {
9799dba64beSDimitry Andric     LLDB_LOGF(log,
9809dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed to send stop "
9810b57cec5SDimitry Andric               "notification for PID %" PRIu64 ", state: eStateExited",
9820b57cec5SDimitry Andric               __FUNCTION__, process->GetID());
9830b57cec5SDimitry Andric   }
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric   // Close the pipe to the inferior terminal i/o if we launched it and set one
9860b57cec5SDimitry Andric   // up.
9870b57cec5SDimitry Andric   MaybeCloseInferiorTerminalConnection();
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric   // We are ready to exit the debug monitor.
9900b57cec5SDimitry Andric   m_exit_now = true;
9910b57cec5SDimitry Andric   m_mainloop.RequestTermination();
9920b57cec5SDimitry Andric }
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
9950b57cec5SDimitry Andric     NativeProcessProtocol *process) {
9960b57cec5SDimitry Andric   assert(process && "process cannot be NULL");
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
9999dba64beSDimitry Andric   LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric   // Send the stop reason unless this is the stop after the launch or attach.
10020b57cec5SDimitry Andric   switch (m_inferior_prev_state) {
10030b57cec5SDimitry Andric   case eStateLaunching:
10040b57cec5SDimitry Andric   case eStateAttaching:
10050b57cec5SDimitry Andric     // Don't send anything per debugserver behavior.
10060b57cec5SDimitry Andric     break;
10070b57cec5SDimitry Andric   default:
10080b57cec5SDimitry Andric     // In all other cases, send the stop reason.
10090b57cec5SDimitry Andric     PacketResult result = SendStopReasonForState(StateType::eStateStopped);
10100b57cec5SDimitry Andric     if (result != PacketResult::Success) {
10119dba64beSDimitry Andric       LLDB_LOGF(log,
10129dba64beSDimitry Andric                 "GDBRemoteCommunicationServerLLGS::%s failed to send stop "
10130b57cec5SDimitry Andric                 "notification for PID %" PRIu64 ", state: eStateExited",
10140b57cec5SDimitry Andric                 __FUNCTION__, process->GetID());
10150b57cec5SDimitry Andric     }
10160b57cec5SDimitry Andric     break;
10170b57cec5SDimitry Andric   }
10180b57cec5SDimitry Andric }
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
10210b57cec5SDimitry Andric     NativeProcessProtocol *process, lldb::StateType state) {
10220b57cec5SDimitry Andric   assert(process && "process cannot be NULL");
10230b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
10240b57cec5SDimitry Andric   if (log) {
10259dba64beSDimitry Andric     LLDB_LOGF(log,
10269dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s called with "
10270b57cec5SDimitry Andric               "NativeProcessProtocol pid %" PRIu64 ", state: %s",
10280b57cec5SDimitry Andric               __FUNCTION__, process->GetID(), StateAsCString(state));
10290b57cec5SDimitry Andric   }
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric   switch (state) {
10320b57cec5SDimitry Andric   case StateType::eStateRunning:
10330b57cec5SDimitry Andric     StartSTDIOForwarding();
10340b57cec5SDimitry Andric     break;
10350b57cec5SDimitry Andric 
10360b57cec5SDimitry Andric   case StateType::eStateStopped:
10370b57cec5SDimitry Andric     // Make sure we get all of the pending stdout/stderr from the inferior and
10380b57cec5SDimitry Andric     // send it to the lldb host before we send the state change notification
10390b57cec5SDimitry Andric     SendProcessOutput();
10400b57cec5SDimitry Andric     // Then stop the forwarding, so that any late output (see llvm.org/pr25652)
10410b57cec5SDimitry Andric     // does not interfere with our protocol.
10420b57cec5SDimitry Andric     StopSTDIOForwarding();
10430b57cec5SDimitry Andric     HandleInferiorState_Stopped(process);
10440b57cec5SDimitry Andric     break;
10450b57cec5SDimitry Andric 
10460b57cec5SDimitry Andric   case StateType::eStateExited:
10470b57cec5SDimitry Andric     // Same as above
10480b57cec5SDimitry Andric     SendProcessOutput();
10490b57cec5SDimitry Andric     StopSTDIOForwarding();
10500b57cec5SDimitry Andric     HandleInferiorState_Exited(process);
10510b57cec5SDimitry Andric     break;
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric   default:
10540b57cec5SDimitry Andric     if (log) {
10559dba64beSDimitry Andric       LLDB_LOGF(log,
10569dba64beSDimitry Andric                 "GDBRemoteCommunicationServerLLGS::%s didn't handle state "
10570b57cec5SDimitry Andric                 "change for pid %" PRIu64 ", new state: %s",
10580b57cec5SDimitry Andric                 __FUNCTION__, process->GetID(), StateAsCString(state));
10590b57cec5SDimitry Andric     }
10600b57cec5SDimitry Andric     break;
10610b57cec5SDimitry Andric   }
10620b57cec5SDimitry Andric 
10630b57cec5SDimitry Andric   // Remember the previous state reported to us.
10640b57cec5SDimitry Andric   m_inferior_prev_state = state;
10650b57cec5SDimitry Andric }
10660b57cec5SDimitry Andric 
10670b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) {
10680b57cec5SDimitry Andric   ClearProcessSpecificData();
10690b57cec5SDimitry Andric }
10700b57cec5SDimitry Andric 
1071fe6060f1SDimitry Andric void GDBRemoteCommunicationServerLLGS::NewSubprocess(
1072fe6060f1SDimitry Andric     NativeProcessProtocol *parent_process,
1073fe6060f1SDimitry Andric     std::unique_ptr<NativeProcessProtocol> child_process) {
1074fe6060f1SDimitry Andric   lldb::pid_t child_pid = child_process->GetID();
1075fe6060f1SDimitry Andric   assert(child_pid != LLDB_INVALID_PROCESS_ID);
1076fe6060f1SDimitry Andric   assert(m_debugged_processes.find(child_pid) == m_debugged_processes.end());
1077fe6060f1SDimitry Andric   m_debugged_processes[child_pid] = std::move(child_process);
1078fe6060f1SDimitry Andric }
1079fe6060f1SDimitry Andric 
10800b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
10810b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
10820b57cec5SDimitry Andric 
10830b57cec5SDimitry Andric   if (!m_handshake_completed) {
10840b57cec5SDimitry Andric     if (!HandshakeWithClient()) {
10859dba64beSDimitry Andric       LLDB_LOGF(log,
10869dba64beSDimitry Andric                 "GDBRemoteCommunicationServerLLGS::%s handshake with "
10870b57cec5SDimitry Andric                 "client failed, exiting",
10880b57cec5SDimitry Andric                 __FUNCTION__);
10890b57cec5SDimitry Andric       m_mainloop.RequestTermination();
10900b57cec5SDimitry Andric       return;
10910b57cec5SDimitry Andric     }
10920b57cec5SDimitry Andric     m_handshake_completed = true;
10930b57cec5SDimitry Andric   }
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric   bool interrupt = false;
10960b57cec5SDimitry Andric   bool done = false;
10970b57cec5SDimitry Andric   Status error;
10980b57cec5SDimitry Andric   while (true) {
10990b57cec5SDimitry Andric     const PacketResult result = GetPacketAndSendResponse(
11000b57cec5SDimitry Andric         std::chrono::microseconds(0), error, interrupt, done);
11010b57cec5SDimitry Andric     if (result == PacketResult::ErrorReplyTimeout)
11020b57cec5SDimitry Andric       break; // No more packets in the queue
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric     if ((result != PacketResult::Success)) {
11059dba64beSDimitry Andric       LLDB_LOGF(log,
11069dba64beSDimitry Andric                 "GDBRemoteCommunicationServerLLGS::%s processing a packet "
11070b57cec5SDimitry Andric                 "failed: %s",
11080b57cec5SDimitry Andric                 __FUNCTION__, error.AsCString());
11090b57cec5SDimitry Andric       m_mainloop.RequestTermination();
11100b57cec5SDimitry Andric       break;
11110b57cec5SDimitry Andric     }
11120b57cec5SDimitry Andric   }
11130b57cec5SDimitry Andric }
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::InitializeConnection(
11165ffd83dbSDimitry Andric     std::unique_ptr<Connection> connection) {
11170b57cec5SDimitry Andric   IOObjectSP read_object_sp = connection->GetReadObject();
11185ffd83dbSDimitry Andric   GDBRemoteCommunicationServer::SetConnection(std::move(connection));
11190b57cec5SDimitry Andric 
11200b57cec5SDimitry Andric   Status error;
11210b57cec5SDimitry Andric   m_network_handle_up = m_mainloop.RegisterReadObject(
11220b57cec5SDimitry Andric       read_object_sp, [this](MainLoopBase &) { DataAvailableCallback(); },
11230b57cec5SDimitry Andric       error);
11240b57cec5SDimitry Andric   return error;
11250b57cec5SDimitry Andric }
11260b57cec5SDimitry Andric 
11270b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
11280b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer,
11290b57cec5SDimitry Andric                                                     uint32_t len) {
11300b57cec5SDimitry Andric   if ((buffer == nullptr) || (len == 0)) {
11310b57cec5SDimitry Andric     // Nothing to send.
11320b57cec5SDimitry Andric     return PacketResult::Success;
11330b57cec5SDimitry Andric   }
11340b57cec5SDimitry Andric 
11350b57cec5SDimitry Andric   StreamString response;
11360b57cec5SDimitry Andric   response.PutChar('O');
11370b57cec5SDimitry Andric   response.PutBytesAsRawHex8(buffer, len);
11380b57cec5SDimitry Andric 
11390b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
11400b57cec5SDimitry Andric }
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) {
11430b57cec5SDimitry Andric   Status error;
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric   // Set up the reading/handling of process I/O
11460b57cec5SDimitry Andric   std::unique_ptr<ConnectionFileDescriptor> conn_up(
11470b57cec5SDimitry Andric       new ConnectionFileDescriptor(fd, true));
11480b57cec5SDimitry Andric   if (!conn_up) {
11490b57cec5SDimitry Andric     error.SetErrorString("failed to create ConnectionFileDescriptor");
11500b57cec5SDimitry Andric     return error;
11510b57cec5SDimitry Andric   }
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric   m_stdio_communication.SetCloseOnEOF(false);
11545ffd83dbSDimitry Andric   m_stdio_communication.SetConnection(std::move(conn_up));
11550b57cec5SDimitry Andric   if (!m_stdio_communication.IsConnected()) {
11560b57cec5SDimitry Andric     error.SetErrorString(
11570b57cec5SDimitry Andric         "failed to set connection for inferior I/O communication");
11580b57cec5SDimitry Andric     return error;
11590b57cec5SDimitry Andric   }
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric   return Status();
11620b57cec5SDimitry Andric }
11630b57cec5SDimitry Andric 
11640b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
11650b57cec5SDimitry Andric   // Don't forward if not connected (e.g. when attaching).
11660b57cec5SDimitry Andric   if (!m_stdio_communication.IsConnected())
11670b57cec5SDimitry Andric     return;
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric   Status error;
11700b57cec5SDimitry Andric   lldbassert(!m_stdio_handle_up);
11710b57cec5SDimitry Andric   m_stdio_handle_up = m_mainloop.RegisterReadObject(
11720b57cec5SDimitry Andric       m_stdio_communication.GetConnection()->GetReadObject(),
11730b57cec5SDimitry Andric       [this](MainLoopBase &) { SendProcessOutput(); }, error);
11740b57cec5SDimitry Andric 
11750b57cec5SDimitry Andric   if (!m_stdio_handle_up) {
11760b57cec5SDimitry Andric     // Not much we can do about the failure. Log it and continue without
11770b57cec5SDimitry Andric     // forwarding.
11780b57cec5SDimitry Andric     if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
11799dba64beSDimitry Andric       LLDB_LOGF(log,
11809dba64beSDimitry Andric                 "GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
11810b57cec5SDimitry Andric                 "forwarding: %s",
11820b57cec5SDimitry Andric                 __FUNCTION__, error.AsCString());
11830b57cec5SDimitry Andric   }
11840b57cec5SDimitry Andric }
11850b57cec5SDimitry Andric 
11860b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() {
11870b57cec5SDimitry Andric   m_stdio_handle_up.reset();
11880b57cec5SDimitry Andric }
11890b57cec5SDimitry Andric 
11900b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SendProcessOutput() {
11910b57cec5SDimitry Andric   char buffer[1024];
11920b57cec5SDimitry Andric   ConnectionStatus status;
11930b57cec5SDimitry Andric   Status error;
11940b57cec5SDimitry Andric   while (true) {
11950b57cec5SDimitry Andric     size_t bytes_read = m_stdio_communication.Read(
11960b57cec5SDimitry Andric         buffer, sizeof buffer, std::chrono::microseconds(0), status, &error);
11970b57cec5SDimitry Andric     switch (status) {
11980b57cec5SDimitry Andric     case eConnectionStatusSuccess:
11990b57cec5SDimitry Andric       SendONotification(buffer, bytes_read);
12000b57cec5SDimitry Andric       break;
12010b57cec5SDimitry Andric     case eConnectionStatusLostConnection:
12020b57cec5SDimitry Andric     case eConnectionStatusEndOfFile:
12030b57cec5SDimitry Andric     case eConnectionStatusError:
12040b57cec5SDimitry Andric     case eConnectionStatusNoConnection:
12050b57cec5SDimitry Andric       if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
12069dba64beSDimitry Andric         LLDB_LOGF(log,
12079dba64beSDimitry Andric                   "GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
12080b57cec5SDimitry Andric                   "forwarding as communication returned status %d (error: "
12090b57cec5SDimitry Andric                   "%s)",
12100b57cec5SDimitry Andric                   __FUNCTION__, status, error.AsCString());
12110b57cec5SDimitry Andric       m_stdio_handle_up.reset();
12120b57cec5SDimitry Andric       return;
12130b57cec5SDimitry Andric 
12140b57cec5SDimitry Andric     case eConnectionStatusInterrupted:
12150b57cec5SDimitry Andric     case eConnectionStatusTimedOut:
12160b57cec5SDimitry Andric       return;
12170b57cec5SDimitry Andric     }
12180b57cec5SDimitry Andric   }
12190b57cec5SDimitry Andric }
12200b57cec5SDimitry Andric 
12210b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
1222fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported(
12230b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
1224fe6060f1SDimitry Andric 
12250b57cec5SDimitry Andric   // Fail if we don't have a current process.
1226fe6060f1SDimitry Andric   if (!m_current_process ||
1227fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
1228fe6060f1SDimitry Andric     return SendErrorResponse(Status("Process not running."));
12290b57cec5SDimitry Andric 
1230fe6060f1SDimitry Andric   return SendJSONResponse(m_current_process->TraceSupported());
12310b57cec5SDimitry Andric }
12320b57cec5SDimitry Andric 
12330b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
1234fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop(
12350b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
12360b57cec5SDimitry Andric   // Fail if we don't have a current process.
1237fe6060f1SDimitry Andric   if (!m_current_process ||
1238fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
1239fe6060f1SDimitry Andric     return SendErrorResponse(Status("Process not running."));
12400b57cec5SDimitry Andric 
1241fe6060f1SDimitry Andric   packet.ConsumeFront("jLLDBTraceStop:");
1242fe6060f1SDimitry Andric   Expected<TraceStopRequest> stop_request =
1243fe6060f1SDimitry Andric       json::parse<TraceStopRequest>(packet.Peek(), "TraceStopRequest");
1244fe6060f1SDimitry Andric   if (!stop_request)
1245fe6060f1SDimitry Andric     return SendErrorResponse(stop_request.takeError());
12460b57cec5SDimitry Andric 
1247fe6060f1SDimitry Andric   if (Error err = m_current_process->TraceStop(*stop_request))
1248fe6060f1SDimitry Andric     return SendErrorResponse(std::move(err));
12490b57cec5SDimitry Andric 
12500b57cec5SDimitry Andric   return SendOKResponse();
12510b57cec5SDimitry Andric }
12520b57cec5SDimitry Andric 
12530b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
1254fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart(
1255e8d8bef9SDimitry Andric     StringExtractorGDBRemote &packet) {
1256e8d8bef9SDimitry Andric 
1257e8d8bef9SDimitry Andric   // Fail if we don't have a current process.
1258fe6060f1SDimitry Andric   if (!m_current_process ||
1259fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
1260e8d8bef9SDimitry Andric     return SendErrorResponse(Status("Process not running."));
1261e8d8bef9SDimitry Andric 
1262fe6060f1SDimitry Andric   packet.ConsumeFront("jLLDBTraceStart:");
1263fe6060f1SDimitry Andric   Expected<TraceStartRequest> request =
1264fe6060f1SDimitry Andric       json::parse<TraceStartRequest>(packet.Peek(), "TraceStartRequest");
1265fe6060f1SDimitry Andric   if (!request)
1266fe6060f1SDimitry Andric     return SendErrorResponse(request.takeError());
1267e8d8bef9SDimitry Andric 
1268fe6060f1SDimitry Andric   if (Error err = m_current_process->TraceStart(packet.Peek(), request->type))
1269fe6060f1SDimitry Andric     return SendErrorResponse(std::move(err));
1270e8d8bef9SDimitry Andric 
1271fe6060f1SDimitry Andric   return SendOKResponse();
1272e8d8bef9SDimitry Andric }
1273e8d8bef9SDimitry Andric 
1274e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult
1275fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState(
12760b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric   // Fail if we don't have a current process.
1279fe6060f1SDimitry Andric   if (!m_current_process ||
1280fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
1281fe6060f1SDimitry Andric     return SendErrorResponse(Status("Process not running."));
12820b57cec5SDimitry Andric 
1283fe6060f1SDimitry Andric   packet.ConsumeFront("jLLDBTraceGetState:");
1284fe6060f1SDimitry Andric   Expected<TraceGetStateRequest> request =
1285fe6060f1SDimitry Andric       json::parse<TraceGetStateRequest>(packet.Peek(), "TraceGetStateRequest");
1286fe6060f1SDimitry Andric   if (!request)
1287fe6060f1SDimitry Andric     return SendErrorResponse(request.takeError());
12880b57cec5SDimitry Andric 
1289fe6060f1SDimitry Andric   return SendJSONResponse(m_current_process->TraceGetState(request->type));
12900b57cec5SDimitry Andric }
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
1293fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData(
12940b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
12950b57cec5SDimitry Andric 
12960b57cec5SDimitry Andric   // Fail if we don't have a current process.
1297fe6060f1SDimitry Andric   if (!m_current_process ||
1298fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
1299fe6060f1SDimitry Andric     return SendErrorResponse(Status("Process not running."));
13000b57cec5SDimitry Andric 
1301fe6060f1SDimitry Andric   packet.ConsumeFront("jLLDBTraceGetBinaryData:");
1302fe6060f1SDimitry Andric   llvm::Expected<TraceGetBinaryDataRequest> request =
1303fe6060f1SDimitry Andric       llvm::json::parse<TraceGetBinaryDataRequest>(packet.Peek(),
1304fe6060f1SDimitry Andric                                                    "TraceGetBinaryDataRequest");
1305fe6060f1SDimitry Andric   if (!request)
1306fe6060f1SDimitry Andric     return SendErrorResponse(Status(request.takeError()));
13070b57cec5SDimitry Andric 
1308fe6060f1SDimitry Andric   if (Expected<std::vector<uint8_t>> bytes =
1309fe6060f1SDimitry Andric           m_current_process->TraceGetBinaryData(*request)) {
13100b57cec5SDimitry Andric     StreamGDBRemote response;
1311fe6060f1SDimitry Andric     response.PutEscapedBytes(bytes->data(), bytes->size());
1312fe6060f1SDimitry Andric     return SendPacketNoLock(response.GetString());
1313fe6060f1SDimitry Andric   } else
1314fe6060f1SDimitry Andric     return SendErrorResponse(bytes.takeError());
13150b57cec5SDimitry Andric }
13160b57cec5SDimitry Andric 
13170b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
13180b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo(
13190b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
13200b57cec5SDimitry Andric   // Fail if we don't have a current process.
1321fe6060f1SDimitry Andric   if (!m_current_process ||
1322fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
13230b57cec5SDimitry Andric     return SendErrorResponse(68);
13240b57cec5SDimitry Andric 
1325fe6060f1SDimitry Andric   lldb::pid_t pid = m_current_process->GetID();
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric   if (pid == LLDB_INVALID_PROCESS_ID)
13280b57cec5SDimitry Andric     return SendErrorResponse(1);
13290b57cec5SDimitry Andric 
13300b57cec5SDimitry Andric   ProcessInstanceInfo proc_info;
13310b57cec5SDimitry Andric   if (!Host::GetProcessInfo(pid, proc_info))
13320b57cec5SDimitry Andric     return SendErrorResponse(1);
13330b57cec5SDimitry Andric 
13340b57cec5SDimitry Andric   StreamString response;
13350b57cec5SDimitry Andric   CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
13360b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
13370b57cec5SDimitry Andric }
13380b57cec5SDimitry Andric 
13390b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
13400b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
13410b57cec5SDimitry Andric   // Fail if we don't have a current process.
1342fe6060f1SDimitry Andric   if (!m_current_process ||
1343fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
13440b57cec5SDimitry Andric     return SendErrorResponse(68);
13450b57cec5SDimitry Andric 
13460b57cec5SDimitry Andric   // Make sure we set the current thread so g and p packets return the data the
13470b57cec5SDimitry Andric   // gdb will expect.
1348fe6060f1SDimitry Andric   lldb::tid_t tid = m_current_process->GetCurrentThreadID();
13490b57cec5SDimitry Andric   SetCurrentThreadID(tid);
13500b57cec5SDimitry Andric 
1351fe6060f1SDimitry Andric   NativeThreadProtocol *thread = m_current_process->GetCurrentThread();
13520b57cec5SDimitry Andric   if (!thread)
13530b57cec5SDimitry Andric     return SendErrorResponse(69);
13540b57cec5SDimitry Andric 
13550b57cec5SDimitry Andric   StreamString response;
13560b57cec5SDimitry Andric   response.Printf("QC%" PRIx64, thread->GetID());
13570b57cec5SDimitry Andric 
13580b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
13590b57cec5SDimitry Andric }
13600b57cec5SDimitry Andric 
13610b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
13620b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) {
13630b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric   StopSTDIOForwarding();
13660b57cec5SDimitry Andric 
1367fe6060f1SDimitry Andric   if (!m_current_process) {
13680b57cec5SDimitry Andric     LLDB_LOG(log, "No debugged process found.");
13690b57cec5SDimitry Andric     return PacketResult::Success;
13700b57cec5SDimitry Andric   }
13710b57cec5SDimitry Andric 
1372fe6060f1SDimitry Andric   Status error = m_current_process->Kill();
13730b57cec5SDimitry Andric   if (error.Fail())
13740b57cec5SDimitry Andric     LLDB_LOG(log, "Failed to kill debugged process {0}: {1}",
1375fe6060f1SDimitry Andric              m_current_process->GetID(), error);
13760b57cec5SDimitry Andric 
13770b57cec5SDimitry Andric   // No OK response for kill packet.
13780b57cec5SDimitry Andric   // return SendOKResponse ();
13790b57cec5SDimitry Andric   return PacketResult::Success;
13800b57cec5SDimitry Andric }
13810b57cec5SDimitry Andric 
13820b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
13830b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR(
13840b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
13850b57cec5SDimitry Andric   packet.SetFilePos(::strlen("QSetDisableASLR:"));
13860b57cec5SDimitry Andric   if (packet.GetU32(0))
13870b57cec5SDimitry Andric     m_process_launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
13880b57cec5SDimitry Andric   else
13890b57cec5SDimitry Andric     m_process_launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
13900b57cec5SDimitry Andric   return SendOKResponse();
13910b57cec5SDimitry Andric }
13920b57cec5SDimitry Andric 
13930b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
13940b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir(
13950b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
13960b57cec5SDimitry Andric   packet.SetFilePos(::strlen("QSetWorkingDir:"));
13970b57cec5SDimitry Andric   std::string path;
13980b57cec5SDimitry Andric   packet.GetHexByteString(path);
13990b57cec5SDimitry Andric   m_process_launch_info.SetWorkingDirectory(FileSpec(path));
14000b57cec5SDimitry Andric   return SendOKResponse();
14010b57cec5SDimitry Andric }
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
14040b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir(
14050b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
14060b57cec5SDimitry Andric   FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
14070b57cec5SDimitry Andric   if (working_dir) {
14080b57cec5SDimitry Andric     StreamString response;
14090b57cec5SDimitry Andric     response.PutStringAsRawHex8(working_dir.GetCString());
14100b57cec5SDimitry Andric     return SendPacketNoLock(response.GetString());
14110b57cec5SDimitry Andric   }
14120b57cec5SDimitry Andric 
14130b57cec5SDimitry Andric   return SendErrorResponse(14);
14140b57cec5SDimitry Andric }
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
1417fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported(
1418fe6060f1SDimitry Andric     StringExtractorGDBRemote &packet) {
1419fe6060f1SDimitry Andric   m_thread_suffix_supported = true;
1420fe6060f1SDimitry Andric   return SendOKResponse();
1421fe6060f1SDimitry Andric }
1422fe6060f1SDimitry Andric 
1423fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult
1424fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply(
1425fe6060f1SDimitry Andric     StringExtractorGDBRemote &packet) {
1426fe6060f1SDimitry Andric   m_list_threads_in_stop_reply = true;
1427fe6060f1SDimitry Andric   return SendOKResponse();
1428fe6060f1SDimitry Andric }
1429fe6060f1SDimitry Andric 
1430fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult
14310b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
14320b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
14339dba64beSDimitry Andric   LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
14340b57cec5SDimitry Andric 
14350b57cec5SDimitry Andric   // Ensure we have a native process.
1436fe6060f1SDimitry Andric   if (!m_continue_process) {
14379dba64beSDimitry Andric     LLDB_LOGF(log,
14389dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s no debugged process "
14390b57cec5SDimitry Andric               "shared pointer",
14400b57cec5SDimitry Andric               __FUNCTION__);
14410b57cec5SDimitry Andric     return SendErrorResponse(0x36);
14420b57cec5SDimitry Andric   }
14430b57cec5SDimitry Andric 
14440b57cec5SDimitry Andric   // Pull out the signal number.
14450b57cec5SDimitry Andric   packet.SetFilePos(::strlen("C"));
14460b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1) {
14470b57cec5SDimitry Andric     // Shouldn't be using a C without a signal.
14480b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "C packet specified without signal.");
14490b57cec5SDimitry Andric   }
14500b57cec5SDimitry Andric   const uint32_t signo =
14510b57cec5SDimitry Andric       packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
14520b57cec5SDimitry Andric   if (signo == std::numeric_limits<uint32_t>::max())
14530b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "failed to parse signal number");
14540b57cec5SDimitry Andric 
14550b57cec5SDimitry Andric   // Handle optional continue address.
14560b57cec5SDimitry Andric   if (packet.GetBytesLeft() > 0) {
14570b57cec5SDimitry Andric     // FIXME add continue at address support for $C{signo}[;{continue-address}].
14580b57cec5SDimitry Andric     if (*packet.Peek() == ';')
14599dba64beSDimitry Andric       return SendUnimplementedResponse(packet.GetStringRef().data());
14600b57cec5SDimitry Andric     else
14610b57cec5SDimitry Andric       return SendIllFormedResponse(
14620b57cec5SDimitry Andric           packet, "unexpected content after $C{signal-number}");
14630b57cec5SDimitry Andric   }
14640b57cec5SDimitry Andric 
14659dba64beSDimitry Andric   ResumeActionList resume_actions(StateType::eStateRunning,
14669dba64beSDimitry Andric                                   LLDB_INVALID_SIGNAL_NUMBER);
14670b57cec5SDimitry Andric   Status error;
14680b57cec5SDimitry Andric 
14690b57cec5SDimitry Andric   // We have two branches: what to do if a continue thread is specified (in
14700b57cec5SDimitry Andric   // which case we target sending the signal to that thread), or when we don't
14710b57cec5SDimitry Andric   // have a continue thread set (in which case we send a signal to the
14720b57cec5SDimitry Andric   // process).
14730b57cec5SDimitry Andric 
14740b57cec5SDimitry Andric   // TODO discuss with Greg Clayton, make sure this makes sense.
14750b57cec5SDimitry Andric 
14760b57cec5SDimitry Andric   lldb::tid_t signal_tid = GetContinueThreadID();
14770b57cec5SDimitry Andric   if (signal_tid != LLDB_INVALID_THREAD_ID) {
14780b57cec5SDimitry Andric     // The resume action for the continue thread (or all threads if a continue
14790b57cec5SDimitry Andric     // thread is not set).
14800b57cec5SDimitry Andric     ResumeAction action = {GetContinueThreadID(), StateType::eStateRunning,
14810b57cec5SDimitry Andric                            static_cast<int>(signo)};
14820b57cec5SDimitry Andric 
14830b57cec5SDimitry Andric     // Add the action for the continue thread (or all threads when the continue
14840b57cec5SDimitry Andric     // thread isn't present).
14850b57cec5SDimitry Andric     resume_actions.Append(action);
14860b57cec5SDimitry Andric   } else {
14870b57cec5SDimitry Andric     // Send the signal to the process since we weren't targeting a specific
14880b57cec5SDimitry Andric     // continue thread with the signal.
1489fe6060f1SDimitry Andric     error = m_continue_process->Signal(signo);
14900b57cec5SDimitry Andric     if (error.Fail()) {
14910b57cec5SDimitry Andric       LLDB_LOG(log, "failed to send signal for process {0}: {1}",
1492fe6060f1SDimitry Andric                m_continue_process->GetID(), error);
14930b57cec5SDimitry Andric 
14940b57cec5SDimitry Andric       return SendErrorResponse(0x52);
14950b57cec5SDimitry Andric     }
14960b57cec5SDimitry Andric   }
14970b57cec5SDimitry Andric 
14980b57cec5SDimitry Andric   // Resume the threads.
1499fe6060f1SDimitry Andric   error = m_continue_process->Resume(resume_actions);
15000b57cec5SDimitry Andric   if (error.Fail()) {
15010b57cec5SDimitry Andric     LLDB_LOG(log, "failed to resume threads for process {0}: {1}",
1502fe6060f1SDimitry Andric              m_continue_process->GetID(), error);
15030b57cec5SDimitry Andric 
15040b57cec5SDimitry Andric     return SendErrorResponse(0x38);
15050b57cec5SDimitry Andric   }
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric   // Don't send an "OK" packet; response is the stopped/exited message.
15080b57cec5SDimitry Andric   return PacketResult::Success;
15090b57cec5SDimitry Andric }
15100b57cec5SDimitry Andric 
15110b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
15120b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
15130b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
15149dba64beSDimitry Andric   LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
15150b57cec5SDimitry Andric 
15160b57cec5SDimitry Andric   packet.SetFilePos(packet.GetFilePos() + ::strlen("c"));
15170b57cec5SDimitry Andric 
15180b57cec5SDimitry Andric   // For now just support all continue.
15190b57cec5SDimitry Andric   const bool has_continue_address = (packet.GetBytesLeft() > 0);
15200b57cec5SDimitry Andric   if (has_continue_address) {
15210b57cec5SDimitry Andric     LLDB_LOG(log, "not implemented for c[address] variant [{0} remains]",
15220b57cec5SDimitry Andric              packet.Peek());
15239dba64beSDimitry Andric     return SendUnimplementedResponse(packet.GetStringRef().data());
15240b57cec5SDimitry Andric   }
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric   // Ensure we have a native process.
1527fe6060f1SDimitry Andric   if (!m_continue_process) {
15289dba64beSDimitry Andric     LLDB_LOGF(log,
15299dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s no debugged process "
15300b57cec5SDimitry Andric               "shared pointer",
15310b57cec5SDimitry Andric               __FUNCTION__);
15320b57cec5SDimitry Andric     return SendErrorResponse(0x36);
15330b57cec5SDimitry Andric   }
15340b57cec5SDimitry Andric 
15350b57cec5SDimitry Andric   // Build the ResumeActionList
15369dba64beSDimitry Andric   ResumeActionList actions(StateType::eStateRunning,
15379dba64beSDimitry Andric                            LLDB_INVALID_SIGNAL_NUMBER);
15380b57cec5SDimitry Andric 
1539fe6060f1SDimitry Andric   Status error = m_continue_process->Resume(actions);
15400b57cec5SDimitry Andric   if (error.Fail()) {
1541fe6060f1SDimitry Andric     LLDB_LOG(log, "c failed for process {0}: {1}", m_continue_process->GetID(),
1542fe6060f1SDimitry Andric              error);
15430b57cec5SDimitry Andric     return SendErrorResponse(GDBRemoteServerError::eErrorResume);
15440b57cec5SDimitry Andric   }
15450b57cec5SDimitry Andric 
1546fe6060f1SDimitry Andric   LLDB_LOG(log, "continued process {0}", m_continue_process->GetID());
15470b57cec5SDimitry Andric   // No response required from continue.
15480b57cec5SDimitry Andric   return PacketResult::Success;
15490b57cec5SDimitry Andric }
15500b57cec5SDimitry Andric 
15510b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
15520b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vCont_actions(
15530b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
15540b57cec5SDimitry Andric   StreamString response;
15550b57cec5SDimitry Andric   response.Printf("vCont;c;C;s;S");
15560b57cec5SDimitry Andric 
15570b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
15580b57cec5SDimitry Andric }
15590b57cec5SDimitry Andric 
15600b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
15610b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vCont(
15620b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
15630b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
15649dba64beSDimitry Andric   LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
15650b57cec5SDimitry Andric             __FUNCTION__);
15660b57cec5SDimitry Andric 
15670b57cec5SDimitry Andric   packet.SetFilePos(::strlen("vCont"));
15680b57cec5SDimitry Andric 
15690b57cec5SDimitry Andric   if (packet.GetBytesLeft() == 0) {
15709dba64beSDimitry Andric     LLDB_LOGF(log,
15719dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s missing action from "
15720b57cec5SDimitry Andric               "vCont package",
15730b57cec5SDimitry Andric               __FUNCTION__);
15740b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Missing action from vCont package");
15750b57cec5SDimitry Andric   }
15760b57cec5SDimitry Andric 
15770b57cec5SDimitry Andric   // Check if this is all continue (no options or ";c").
15780b57cec5SDimitry Andric   if (::strcmp(packet.Peek(), ";c") == 0) {
15790b57cec5SDimitry Andric     // Move past the ';', then do a simple 'c'.
15800b57cec5SDimitry Andric     packet.SetFilePos(packet.GetFilePos() + 1);
15810b57cec5SDimitry Andric     return Handle_c(packet);
15820b57cec5SDimitry Andric   } else if (::strcmp(packet.Peek(), ";s") == 0) {
15830b57cec5SDimitry Andric     // Move past the ';', then do a simple 's'.
15840b57cec5SDimitry Andric     packet.SetFilePos(packet.GetFilePos() + 1);
15850b57cec5SDimitry Andric     return Handle_s(packet);
15860b57cec5SDimitry Andric   }
15870b57cec5SDimitry Andric 
15880b57cec5SDimitry Andric   // Ensure we have a native process.
1589fe6060f1SDimitry Andric   if (!m_continue_process) {
15900b57cec5SDimitry Andric     LLDB_LOG(log, "no debugged process");
15910b57cec5SDimitry Andric     return SendErrorResponse(0x36);
15920b57cec5SDimitry Andric   }
15930b57cec5SDimitry Andric 
15940b57cec5SDimitry Andric   ResumeActionList thread_actions;
15950b57cec5SDimitry Andric 
15960b57cec5SDimitry Andric   while (packet.GetBytesLeft() && *packet.Peek() == ';') {
15970b57cec5SDimitry Andric     // Skip the semi-colon.
15980b57cec5SDimitry Andric     packet.GetChar();
15990b57cec5SDimitry Andric 
16000b57cec5SDimitry Andric     // Build up the thread action.
16010b57cec5SDimitry Andric     ResumeAction thread_action;
16020b57cec5SDimitry Andric     thread_action.tid = LLDB_INVALID_THREAD_ID;
16030b57cec5SDimitry Andric     thread_action.state = eStateInvalid;
16049dba64beSDimitry Andric     thread_action.signal = LLDB_INVALID_SIGNAL_NUMBER;
16050b57cec5SDimitry Andric 
16060b57cec5SDimitry Andric     const char action = packet.GetChar();
16070b57cec5SDimitry Andric     switch (action) {
16080b57cec5SDimitry Andric     case 'C':
16090b57cec5SDimitry Andric       thread_action.signal = packet.GetHexMaxU32(false, 0);
16100b57cec5SDimitry Andric       if (thread_action.signal == 0)
16110b57cec5SDimitry Andric         return SendIllFormedResponse(
16120b57cec5SDimitry Andric             packet, "Could not parse signal in vCont packet C action");
16130b57cec5SDimitry Andric       LLVM_FALLTHROUGH;
16140b57cec5SDimitry Andric 
16150b57cec5SDimitry Andric     case 'c':
16160b57cec5SDimitry Andric       // Continue
16170b57cec5SDimitry Andric       thread_action.state = eStateRunning;
16180b57cec5SDimitry Andric       break;
16190b57cec5SDimitry Andric 
16200b57cec5SDimitry Andric     case 'S':
16210b57cec5SDimitry Andric       thread_action.signal = packet.GetHexMaxU32(false, 0);
16220b57cec5SDimitry Andric       if (thread_action.signal == 0)
16230b57cec5SDimitry Andric         return SendIllFormedResponse(
16240b57cec5SDimitry Andric             packet, "Could not parse signal in vCont packet S action");
16250b57cec5SDimitry Andric       LLVM_FALLTHROUGH;
16260b57cec5SDimitry Andric 
16270b57cec5SDimitry Andric     case 's':
16280b57cec5SDimitry Andric       // Step
16290b57cec5SDimitry Andric       thread_action.state = eStateStepping;
16300b57cec5SDimitry Andric       break;
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric     default:
16330b57cec5SDimitry Andric       return SendIllFormedResponse(packet, "Unsupported vCont action");
16340b57cec5SDimitry Andric       break;
16350b57cec5SDimitry Andric     }
16360b57cec5SDimitry Andric 
16370b57cec5SDimitry Andric     // Parse out optional :{thread-id} value.
16380b57cec5SDimitry Andric     if (packet.GetBytesLeft() && (*packet.Peek() == ':')) {
16390b57cec5SDimitry Andric       // Consume the separator.
16400b57cec5SDimitry Andric       packet.GetChar();
16410b57cec5SDimitry Andric 
1642fe6060f1SDimitry Andric       llvm::Expected<lldb::tid_t> tid_ret =
1643fe6060f1SDimitry Andric           ReadTid(packet, /*allow_all=*/true, m_continue_process->GetID());
1644fe6060f1SDimitry Andric       if (!tid_ret)
1645fe6060f1SDimitry Andric         return SendErrorResponse(tid_ret.takeError());
1646fe6060f1SDimitry Andric 
1647fe6060f1SDimitry Andric       thread_action.tid = tid_ret.get();
1648fe6060f1SDimitry Andric       if (thread_action.tid == StringExtractorGDBRemote::AllThreads)
1649fe6060f1SDimitry Andric         thread_action.tid = LLDB_INVALID_THREAD_ID;
16500b57cec5SDimitry Andric     }
16510b57cec5SDimitry Andric 
16520b57cec5SDimitry Andric     thread_actions.Append(thread_action);
16530b57cec5SDimitry Andric   }
16540b57cec5SDimitry Andric 
1655fe6060f1SDimitry Andric   Status error = m_continue_process->Resume(thread_actions);
16560b57cec5SDimitry Andric   if (error.Fail()) {
16570b57cec5SDimitry Andric     LLDB_LOG(log, "vCont failed for process {0}: {1}",
1658fe6060f1SDimitry Andric              m_continue_process->GetID(), error);
16590b57cec5SDimitry Andric     return SendErrorResponse(GDBRemoteServerError::eErrorResume);
16600b57cec5SDimitry Andric   }
16610b57cec5SDimitry Andric 
1662fe6060f1SDimitry Andric   LLDB_LOG(log, "continued process {0}", m_continue_process->GetID());
16630b57cec5SDimitry Andric   // No response required from vCont.
16640b57cec5SDimitry Andric   return PacketResult::Success;
16650b57cec5SDimitry Andric }
16660b57cec5SDimitry Andric 
16670b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) {
16680b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
16690b57cec5SDimitry Andric   LLDB_LOG(log, "setting current thread id to {0}", tid);
16700b57cec5SDimitry Andric 
16710b57cec5SDimitry Andric   m_current_tid = tid;
1672fe6060f1SDimitry Andric   if (m_current_process)
1673fe6060f1SDimitry Andric     m_current_process->SetCurrentThreadID(m_current_tid);
16740b57cec5SDimitry Andric }
16750b57cec5SDimitry Andric 
16760b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) {
16770b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
16780b57cec5SDimitry Andric   LLDB_LOG(log, "setting continue thread id to {0}", tid);
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric   m_continue_tid = tid;
16810b57cec5SDimitry Andric }
16820b57cec5SDimitry Andric 
16830b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
16840b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_stop_reason(
16850b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
16860b57cec5SDimitry Andric   // Handle the $? gdbremote command.
16870b57cec5SDimitry Andric 
16880b57cec5SDimitry Andric   // If no process, indicate error
1689fe6060f1SDimitry Andric   if (!m_current_process)
16900b57cec5SDimitry Andric     return SendErrorResponse(02);
16910b57cec5SDimitry Andric 
1692fe6060f1SDimitry Andric   return SendStopReasonForState(m_current_process->GetState());
16930b57cec5SDimitry Andric }
16940b57cec5SDimitry Andric 
16950b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
16960b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
16970b57cec5SDimitry Andric     lldb::StateType process_state) {
16980b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
16990b57cec5SDimitry Andric 
17000b57cec5SDimitry Andric   switch (process_state) {
17010b57cec5SDimitry Andric   case eStateAttaching:
17020b57cec5SDimitry Andric   case eStateLaunching:
17030b57cec5SDimitry Andric   case eStateRunning:
17040b57cec5SDimitry Andric   case eStateStepping:
17050b57cec5SDimitry Andric   case eStateDetached:
17060b57cec5SDimitry Andric     // NOTE: gdb protocol doc looks like it should return $OK
17070b57cec5SDimitry Andric     // when everything is running (i.e. no stopped result).
17080b57cec5SDimitry Andric     return PacketResult::Success; // Ignore
17090b57cec5SDimitry Andric 
17100b57cec5SDimitry Andric   case eStateSuspended:
17110b57cec5SDimitry Andric   case eStateStopped:
17120b57cec5SDimitry Andric   case eStateCrashed: {
1713fe6060f1SDimitry Andric     assert(m_current_process != nullptr);
1714fe6060f1SDimitry Andric     lldb::tid_t tid = m_current_process->GetCurrentThreadID();
17150b57cec5SDimitry Andric     // Make sure we set the current thread so g and p packets return the data
17160b57cec5SDimitry Andric     // the gdb will expect.
17170b57cec5SDimitry Andric     SetCurrentThreadID(tid);
17180b57cec5SDimitry Andric     return SendStopReplyPacketForThread(tid);
17190b57cec5SDimitry Andric   }
17200b57cec5SDimitry Andric 
17210b57cec5SDimitry Andric   case eStateInvalid:
17220b57cec5SDimitry Andric   case eStateUnloaded:
17230b57cec5SDimitry Andric   case eStateExited:
1724fe6060f1SDimitry Andric     return SendWResponse(m_current_process);
17250b57cec5SDimitry Andric 
17260b57cec5SDimitry Andric   default:
17270b57cec5SDimitry Andric     LLDB_LOG(log, "pid {0}, current state reporting not handled: {1}",
1728fe6060f1SDimitry Andric              m_current_process->GetID(), process_state);
17290b57cec5SDimitry Andric     break;
17300b57cec5SDimitry Andric   }
17310b57cec5SDimitry Andric 
17320b57cec5SDimitry Andric   return SendErrorResponse(0);
17330b57cec5SDimitry Andric }
17340b57cec5SDimitry Andric 
17350b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
17360b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
17370b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
17380b57cec5SDimitry Andric   // Fail if we don't have a current process.
1739fe6060f1SDimitry Andric   if (!m_current_process ||
1740fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
17410b57cec5SDimitry Andric     return SendErrorResponse(68);
17420b57cec5SDimitry Andric 
17430b57cec5SDimitry Andric   // Ensure we have a thread.
1744fe6060f1SDimitry Andric   NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0);
17450b57cec5SDimitry Andric   if (!thread)
17460b57cec5SDimitry Andric     return SendErrorResponse(69);
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric   // Get the register context for the first thread.
17490b57cec5SDimitry Andric   NativeRegisterContext &reg_context = thread->GetRegisterContext();
17500b57cec5SDimitry Andric 
17510b57cec5SDimitry Andric   // Parse out the register number from the request.
17520b57cec5SDimitry Andric   packet.SetFilePos(strlen("qRegisterInfo"));
17530b57cec5SDimitry Andric   const uint32_t reg_index =
17540b57cec5SDimitry Andric       packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
17550b57cec5SDimitry Andric   if (reg_index == std::numeric_limits<uint32_t>::max())
17560b57cec5SDimitry Andric     return SendErrorResponse(69);
17570b57cec5SDimitry Andric 
17580b57cec5SDimitry Andric   // Return the end of registers response if we've iterated one past the end of
17590b57cec5SDimitry Andric   // the register set.
17600b57cec5SDimitry Andric   if (reg_index >= reg_context.GetUserRegisterCount())
17610b57cec5SDimitry Andric     return SendErrorResponse(69);
17620b57cec5SDimitry Andric 
17630b57cec5SDimitry Andric   const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
17640b57cec5SDimitry Andric   if (!reg_info)
17650b57cec5SDimitry Andric     return SendErrorResponse(69);
17660b57cec5SDimitry Andric 
17670b57cec5SDimitry Andric   // Build the reginfos response.
17680b57cec5SDimitry Andric   StreamGDBRemote response;
17690b57cec5SDimitry Andric 
17700b57cec5SDimitry Andric   response.PutCString("name:");
17710b57cec5SDimitry Andric   response.PutCString(reg_info->name);
17720b57cec5SDimitry Andric   response.PutChar(';');
17730b57cec5SDimitry Andric 
17740b57cec5SDimitry Andric   if (reg_info->alt_name && reg_info->alt_name[0]) {
17750b57cec5SDimitry Andric     response.PutCString("alt-name:");
17760b57cec5SDimitry Andric     response.PutCString(reg_info->alt_name);
17770b57cec5SDimitry Andric     response.PutChar(';');
17780b57cec5SDimitry Andric   }
17790b57cec5SDimitry Andric 
1780e8d8bef9SDimitry Andric   response.Printf("bitsize:%" PRIu32 ";", reg_info->byte_size * 8);
1781e8d8bef9SDimitry Andric 
1782e8d8bef9SDimitry Andric   if (!reg_context.RegisterOffsetIsDynamic())
1783e8d8bef9SDimitry Andric     response.Printf("offset:%" PRIu32 ";", reg_info->byte_offset);
17840b57cec5SDimitry Andric 
17855ffd83dbSDimitry Andric   llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info);
17865ffd83dbSDimitry Andric   if (!encoding.empty())
17875ffd83dbSDimitry Andric     response << "encoding:" << encoding << ';';
17880b57cec5SDimitry Andric 
17895ffd83dbSDimitry Andric   llvm::StringRef format = GetFormatNameOrEmpty(*reg_info);
17905ffd83dbSDimitry Andric   if (!format.empty())
17915ffd83dbSDimitry Andric     response << "format:" << format << ';';
17920b57cec5SDimitry Andric 
17930b57cec5SDimitry Andric   const char *const register_set_name =
17940b57cec5SDimitry Andric       reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
17955ffd83dbSDimitry Andric   if (register_set_name)
17965ffd83dbSDimitry Andric     response << "set:" << register_set_name << ';';
17970b57cec5SDimitry Andric 
17980b57cec5SDimitry Andric   if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] !=
17990b57cec5SDimitry Andric       LLDB_INVALID_REGNUM)
18000b57cec5SDimitry Andric     response.Printf("ehframe:%" PRIu32 ";",
18010b57cec5SDimitry Andric                     reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
18020b57cec5SDimitry Andric 
18030b57cec5SDimitry Andric   if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
18040b57cec5SDimitry Andric     response.Printf("dwarf:%" PRIu32 ";",
18050b57cec5SDimitry Andric                     reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
18060b57cec5SDimitry Andric 
18075ffd83dbSDimitry Andric   llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info);
18085ffd83dbSDimitry Andric   if (!kind_generic.empty())
18095ffd83dbSDimitry Andric     response << "generic:" << kind_generic << ';';
18100b57cec5SDimitry Andric 
18110b57cec5SDimitry Andric   if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
18120b57cec5SDimitry Andric     response.PutCString("container-regs:");
18135ffd83dbSDimitry Andric     CollectRegNums(reg_info->value_regs, response, true);
18140b57cec5SDimitry Andric     response.PutChar(';');
18150b57cec5SDimitry Andric   }
18160b57cec5SDimitry Andric 
18170b57cec5SDimitry Andric   if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) {
18180b57cec5SDimitry Andric     response.PutCString("invalidate-regs:");
18195ffd83dbSDimitry Andric     CollectRegNums(reg_info->invalidate_regs, response, true);
18200b57cec5SDimitry Andric     response.PutChar(';');
18210b57cec5SDimitry Andric   }
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric   if (reg_info->dynamic_size_dwarf_expr_bytes) {
18240b57cec5SDimitry Andric     const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
18250b57cec5SDimitry Andric     response.PutCString("dynamic_size_dwarf_expr_bytes:");
18260b57cec5SDimitry Andric     for (uint32_t i = 0; i < dwarf_opcode_len; ++i)
18270b57cec5SDimitry Andric       response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]);
18280b57cec5SDimitry Andric     response.PutChar(';');
18290b57cec5SDimitry Andric   }
18300b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
18310b57cec5SDimitry Andric }
18320b57cec5SDimitry Andric 
18330b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
18340b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
18350b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
18360b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
18370b57cec5SDimitry Andric 
18380b57cec5SDimitry Andric   // Fail if we don't have a current process.
1839fe6060f1SDimitry Andric   if (!m_current_process ||
1840fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
18410b57cec5SDimitry Andric     LLDB_LOG(log, "no process ({0}), returning OK",
1842fe6060f1SDimitry Andric              m_current_process ? "invalid process id"
1843fe6060f1SDimitry Andric                                : "null m_current_process");
18440b57cec5SDimitry Andric     return SendOKResponse();
18450b57cec5SDimitry Andric   }
18460b57cec5SDimitry Andric 
18470b57cec5SDimitry Andric   StreamGDBRemote response;
18480b57cec5SDimitry Andric   response.PutChar('m');
18490b57cec5SDimitry Andric 
18500b57cec5SDimitry Andric   LLDB_LOG(log, "starting thread iteration");
18510b57cec5SDimitry Andric   NativeThreadProtocol *thread;
18520b57cec5SDimitry Andric   uint32_t thread_index;
18530b57cec5SDimitry Andric   for (thread_index = 0,
1854fe6060f1SDimitry Andric       thread = m_current_process->GetThreadAtIndex(thread_index);
18550b57cec5SDimitry Andric        thread; ++thread_index,
1856fe6060f1SDimitry Andric       thread = m_current_process->GetThreadAtIndex(thread_index)) {
18570b57cec5SDimitry Andric     LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index,
18580b57cec5SDimitry Andric              thread->GetID());
18590b57cec5SDimitry Andric     if (thread_index > 0)
18600b57cec5SDimitry Andric       response.PutChar(',');
18610b57cec5SDimitry Andric     response.Printf("%" PRIx64, thread->GetID());
18620b57cec5SDimitry Andric   }
18630b57cec5SDimitry Andric 
18640b57cec5SDimitry Andric   LLDB_LOG(log, "finished thread iteration");
18650b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
18660b57cec5SDimitry Andric }
18670b57cec5SDimitry Andric 
18680b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
18690b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo(
18700b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
18710b57cec5SDimitry Andric   // FIXME for now we return the full thread list in the initial packet and
18720b57cec5SDimitry Andric   // always do nothing here.
18730b57cec5SDimitry Andric   return SendPacketNoLock("l");
18740b57cec5SDimitry Andric }
18750b57cec5SDimitry Andric 
18760b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
18770b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) {
18780b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
18790b57cec5SDimitry Andric 
18800b57cec5SDimitry Andric   // Move past packet name.
18810b57cec5SDimitry Andric   packet.SetFilePos(strlen("g"));
18820b57cec5SDimitry Andric 
18830b57cec5SDimitry Andric   // Get the thread to use.
18840b57cec5SDimitry Andric   NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
18850b57cec5SDimitry Andric   if (!thread) {
18860b57cec5SDimitry Andric     LLDB_LOG(log, "failed, no thread available");
18870b57cec5SDimitry Andric     return SendErrorResponse(0x15);
18880b57cec5SDimitry Andric   }
18890b57cec5SDimitry Andric 
18900b57cec5SDimitry Andric   // Get the thread's register context.
18910b57cec5SDimitry Andric   NativeRegisterContext &reg_ctx = thread->GetRegisterContext();
18920b57cec5SDimitry Andric 
18930b57cec5SDimitry Andric   std::vector<uint8_t> regs_buffer;
18940b57cec5SDimitry Andric   for (uint32_t reg_num = 0; reg_num < reg_ctx.GetUserRegisterCount();
18950b57cec5SDimitry Andric        ++reg_num) {
18960b57cec5SDimitry Andric     const RegisterInfo *reg_info = reg_ctx.GetRegisterInfoAtIndex(reg_num);
18970b57cec5SDimitry Andric 
18980b57cec5SDimitry Andric     if (reg_info == nullptr) {
18990b57cec5SDimitry Andric       LLDB_LOG(log, "failed to get register info for register index {0}",
19000b57cec5SDimitry Andric                reg_num);
19010b57cec5SDimitry Andric       return SendErrorResponse(0x15);
19020b57cec5SDimitry Andric     }
19030b57cec5SDimitry Andric 
19040b57cec5SDimitry Andric     if (reg_info->value_regs != nullptr)
19050b57cec5SDimitry Andric       continue; // skip registers that are contained in other registers
19060b57cec5SDimitry Andric 
19070b57cec5SDimitry Andric     RegisterValue reg_value;
19080b57cec5SDimitry Andric     Status error = reg_ctx.ReadRegister(reg_info, reg_value);
19090b57cec5SDimitry Andric     if (error.Fail()) {
19100b57cec5SDimitry Andric       LLDB_LOG(log, "failed to read register at index {0}", reg_num);
19110b57cec5SDimitry Andric       return SendErrorResponse(0x15);
19120b57cec5SDimitry Andric     }
19130b57cec5SDimitry Andric 
19140b57cec5SDimitry Andric     if (reg_info->byte_offset + reg_info->byte_size >= regs_buffer.size())
19150b57cec5SDimitry Andric       // Resize the buffer to guarantee it can store the register offsetted
19160b57cec5SDimitry Andric       // data.
19170b57cec5SDimitry Andric       regs_buffer.resize(reg_info->byte_offset + reg_info->byte_size);
19180b57cec5SDimitry Andric 
19190b57cec5SDimitry Andric     // Copy the register offsetted data to the buffer.
19200b57cec5SDimitry Andric     memcpy(regs_buffer.data() + reg_info->byte_offset, reg_value.GetBytes(),
19210b57cec5SDimitry Andric            reg_info->byte_size);
19220b57cec5SDimitry Andric   }
19230b57cec5SDimitry Andric 
19240b57cec5SDimitry Andric   // Write the response.
19250b57cec5SDimitry Andric   StreamGDBRemote response;
19260b57cec5SDimitry Andric   response.PutBytesAsRawHex8(regs_buffer.data(), regs_buffer.size());
19270b57cec5SDimitry Andric 
19280b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
19290b57cec5SDimitry Andric }
19300b57cec5SDimitry Andric 
19310b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
19320b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
19330b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
19340b57cec5SDimitry Andric 
19350b57cec5SDimitry Andric   // Parse out the register number from the request.
19360b57cec5SDimitry Andric   packet.SetFilePos(strlen("p"));
19370b57cec5SDimitry Andric   const uint32_t reg_index =
19380b57cec5SDimitry Andric       packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
19390b57cec5SDimitry Andric   if (reg_index == std::numeric_limits<uint32_t>::max()) {
19409dba64beSDimitry Andric     LLDB_LOGF(log,
19419dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, could not "
19420b57cec5SDimitry Andric               "parse register number from request \"%s\"",
19439dba64beSDimitry Andric               __FUNCTION__, packet.GetStringRef().data());
19440b57cec5SDimitry Andric     return SendErrorResponse(0x15);
19450b57cec5SDimitry Andric   }
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric   // Get the thread to use.
19480b57cec5SDimitry Andric   NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
19490b57cec5SDimitry Andric   if (!thread) {
19500b57cec5SDimitry Andric     LLDB_LOG(log, "failed, no thread available");
19510b57cec5SDimitry Andric     return SendErrorResponse(0x15);
19520b57cec5SDimitry Andric   }
19530b57cec5SDimitry Andric 
19540b57cec5SDimitry Andric   // Get the thread's register context.
19550b57cec5SDimitry Andric   NativeRegisterContext &reg_context = thread->GetRegisterContext();
19560b57cec5SDimitry Andric 
19570b57cec5SDimitry Andric   // Return the end of registers response if we've iterated one past the end of
19580b57cec5SDimitry Andric   // the register set.
19590b57cec5SDimitry Andric   if (reg_index >= reg_context.GetUserRegisterCount()) {
19609dba64beSDimitry Andric     LLDB_LOGF(log,
19619dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, requested "
19620b57cec5SDimitry Andric               "register %" PRIu32 " beyond register count %" PRIu32,
19639dba64beSDimitry Andric               __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
19640b57cec5SDimitry Andric     return SendErrorResponse(0x15);
19650b57cec5SDimitry Andric   }
19660b57cec5SDimitry Andric 
19670b57cec5SDimitry Andric   const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
19680b57cec5SDimitry Andric   if (!reg_info) {
19699dba64beSDimitry Andric     LLDB_LOGF(log,
19709dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, requested "
19710b57cec5SDimitry Andric               "register %" PRIu32 " returned NULL",
19720b57cec5SDimitry Andric               __FUNCTION__, reg_index);
19730b57cec5SDimitry Andric     return SendErrorResponse(0x15);
19740b57cec5SDimitry Andric   }
19750b57cec5SDimitry Andric 
19760b57cec5SDimitry Andric   // Build the reginfos response.
19770b57cec5SDimitry Andric   StreamGDBRemote response;
19780b57cec5SDimitry Andric 
19790b57cec5SDimitry Andric   // Retrieve the value
19800b57cec5SDimitry Andric   RegisterValue reg_value;
19810b57cec5SDimitry Andric   Status error = reg_context.ReadRegister(reg_info, reg_value);
19820b57cec5SDimitry Andric   if (error.Fail()) {
19839dba64beSDimitry Andric     LLDB_LOGF(log,
19849dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, read of "
19850b57cec5SDimitry Andric               "requested register %" PRIu32 " (%s) failed: %s",
19860b57cec5SDimitry Andric               __FUNCTION__, reg_index, reg_info->name, error.AsCString());
19870b57cec5SDimitry Andric     return SendErrorResponse(0x15);
19880b57cec5SDimitry Andric   }
19890b57cec5SDimitry Andric 
19900b57cec5SDimitry Andric   const uint8_t *const data =
1991480093f4SDimitry Andric       static_cast<const uint8_t *>(reg_value.GetBytes());
19920b57cec5SDimitry Andric   if (!data) {
19939dba64beSDimitry Andric     LLDB_LOGF(log,
19949dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed to get data "
19950b57cec5SDimitry Andric               "bytes from requested register %" PRIu32,
19960b57cec5SDimitry Andric               __FUNCTION__, reg_index);
19970b57cec5SDimitry Andric     return SendErrorResponse(0x15);
19980b57cec5SDimitry Andric   }
19990b57cec5SDimitry Andric 
20000b57cec5SDimitry Andric   // FIXME flip as needed to get data in big/little endian format for this host.
20010b57cec5SDimitry Andric   for (uint32_t i = 0; i < reg_value.GetByteSize(); ++i)
20020b57cec5SDimitry Andric     response.PutHex8(data[i]);
20030b57cec5SDimitry Andric 
20040b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
20050b57cec5SDimitry Andric }
20060b57cec5SDimitry Andric 
20070b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
20080b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
20090b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
20100b57cec5SDimitry Andric 
20110b57cec5SDimitry Andric   // Ensure there is more content.
20120b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
20130b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Empty P packet");
20140b57cec5SDimitry Andric 
20150b57cec5SDimitry Andric   // Parse out the register number from the request.
20160b57cec5SDimitry Andric   packet.SetFilePos(strlen("P"));
20170b57cec5SDimitry Andric   const uint32_t reg_index =
20180b57cec5SDimitry Andric       packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
20190b57cec5SDimitry Andric   if (reg_index == std::numeric_limits<uint32_t>::max()) {
20209dba64beSDimitry Andric     LLDB_LOGF(log,
20219dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, could not "
20220b57cec5SDimitry Andric               "parse register number from request \"%s\"",
20239dba64beSDimitry Andric               __FUNCTION__, packet.GetStringRef().data());
20240b57cec5SDimitry Andric     return SendErrorResponse(0x29);
20250b57cec5SDimitry Andric   }
20260b57cec5SDimitry Andric 
20270b57cec5SDimitry Andric   // Note debugserver would send an E30 here.
20280b57cec5SDimitry Andric   if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != '='))
20290b57cec5SDimitry Andric     return SendIllFormedResponse(
20300b57cec5SDimitry Andric         packet, "P packet missing '=' char after register number");
20310b57cec5SDimitry Andric 
20320b57cec5SDimitry Andric   // Parse out the value.
20335ffd83dbSDimitry Andric   uint8_t reg_bytes[RegisterValue::kMaxRegisterByteSize];
20340b57cec5SDimitry Andric   size_t reg_size = packet.GetHexBytesAvail(reg_bytes);
20350b57cec5SDimitry Andric 
20360b57cec5SDimitry Andric   // Get the thread to use.
20370b57cec5SDimitry Andric   NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
20380b57cec5SDimitry Andric   if (!thread) {
20399dba64beSDimitry Andric     LLDB_LOGF(log,
20409dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, no thread "
20410b57cec5SDimitry Andric               "available (thread index 0)",
20420b57cec5SDimitry Andric               __FUNCTION__);
20430b57cec5SDimitry Andric     return SendErrorResponse(0x28);
20440b57cec5SDimitry Andric   }
20450b57cec5SDimitry Andric 
20460b57cec5SDimitry Andric   // Get the thread's register context.
20470b57cec5SDimitry Andric   NativeRegisterContext &reg_context = thread->GetRegisterContext();
20480b57cec5SDimitry Andric   const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
20490b57cec5SDimitry Andric   if (!reg_info) {
20509dba64beSDimitry Andric     LLDB_LOGF(log,
20519dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, requested "
20520b57cec5SDimitry Andric               "register %" PRIu32 " returned NULL",
20530b57cec5SDimitry Andric               __FUNCTION__, reg_index);
20540b57cec5SDimitry Andric     return SendErrorResponse(0x48);
20550b57cec5SDimitry Andric   }
20560b57cec5SDimitry Andric 
20570b57cec5SDimitry Andric   // Return the end of registers response if we've iterated one past the end of
20580b57cec5SDimitry Andric   // the register set.
20590b57cec5SDimitry Andric   if (reg_index >= reg_context.GetUserRegisterCount()) {
20609dba64beSDimitry Andric     LLDB_LOGF(log,
20619dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, requested "
20620b57cec5SDimitry Andric               "register %" PRIu32 " beyond register count %" PRIu32,
20630b57cec5SDimitry Andric               __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
20640b57cec5SDimitry Andric     return SendErrorResponse(0x47);
20650b57cec5SDimitry Andric   }
20660b57cec5SDimitry Andric 
20670b57cec5SDimitry Andric   // The dwarf expression are evaluate on host site which may cause register
20680b57cec5SDimitry Andric   // size to change Hence the reg_size may not be same as reg_info->bytes_size
20690b57cec5SDimitry Andric   if ((reg_size != reg_info->byte_size) &&
20700b57cec5SDimitry Andric       !(reg_info->dynamic_size_dwarf_expr_bytes)) {
20710b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "P packet register size is incorrect");
20720b57cec5SDimitry Andric   }
20730b57cec5SDimitry Andric 
20740b57cec5SDimitry Andric   // Build the reginfos response.
20750b57cec5SDimitry Andric   StreamGDBRemote response;
20760b57cec5SDimitry Andric 
2077fe6060f1SDimitry Andric   RegisterValue reg_value(makeArrayRef(reg_bytes, reg_size),
2078fe6060f1SDimitry Andric                           m_current_process->GetArchitecture().GetByteOrder());
20790b57cec5SDimitry Andric   Status error = reg_context.WriteRegister(reg_info, reg_value);
20800b57cec5SDimitry Andric   if (error.Fail()) {
20819dba64beSDimitry Andric     LLDB_LOGF(log,
20829dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, write of "
20830b57cec5SDimitry Andric               "requested register %" PRIu32 " (%s) failed: %s",
20840b57cec5SDimitry Andric               __FUNCTION__, reg_index, reg_info->name, error.AsCString());
20850b57cec5SDimitry Andric     return SendErrorResponse(0x32);
20860b57cec5SDimitry Andric   }
20870b57cec5SDimitry Andric 
20880b57cec5SDimitry Andric   return SendOKResponse();
20890b57cec5SDimitry Andric }
20900b57cec5SDimitry Andric 
20910b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
20920b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
20930b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
20940b57cec5SDimitry Andric 
20950b57cec5SDimitry Andric   // Parse out which variant of $H is requested.
20960b57cec5SDimitry Andric   packet.SetFilePos(strlen("H"));
20970b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1) {
20989dba64beSDimitry Andric     LLDB_LOGF(log,
20999dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, H command "
21000b57cec5SDimitry Andric               "missing {g,c} variant",
21010b57cec5SDimitry Andric               __FUNCTION__);
21020b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "H command missing {g,c} variant");
21030b57cec5SDimitry Andric   }
21040b57cec5SDimitry Andric 
21050b57cec5SDimitry Andric   const char h_variant = packet.GetChar();
2106fe6060f1SDimitry Andric   NativeProcessProtocol *default_process;
21070b57cec5SDimitry Andric   switch (h_variant) {
21080b57cec5SDimitry Andric   case 'g':
2109fe6060f1SDimitry Andric     default_process = m_current_process;
21100b57cec5SDimitry Andric     break;
21110b57cec5SDimitry Andric 
21120b57cec5SDimitry Andric   case 'c':
2113fe6060f1SDimitry Andric     default_process = m_continue_process;
21140b57cec5SDimitry Andric     break;
21150b57cec5SDimitry Andric 
21160b57cec5SDimitry Andric   default:
21179dba64beSDimitry Andric     LLDB_LOGF(
21189dba64beSDimitry Andric         log,
21190b57cec5SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c",
21200b57cec5SDimitry Andric         __FUNCTION__, h_variant);
21210b57cec5SDimitry Andric     return SendIllFormedResponse(packet,
21220b57cec5SDimitry Andric                                  "H variant unsupported, should be c or g");
21230b57cec5SDimitry Andric   }
21240b57cec5SDimitry Andric 
21250b57cec5SDimitry Andric   // Parse out the thread number.
2126fe6060f1SDimitry Andric   auto pid_tid = packet.GetPidTid(default_process ? default_process->GetID()
2127fe6060f1SDimitry Andric                                                   : LLDB_INVALID_PROCESS_ID);
2128fe6060f1SDimitry Andric   if (!pid_tid)
2129fe6060f1SDimitry Andric     return SendErrorResponse(llvm::make_error<StringError>(
2130fe6060f1SDimitry Andric         inconvertibleErrorCode(), "Malformed thread-id"));
2131fe6060f1SDimitry Andric 
2132fe6060f1SDimitry Andric   lldb::pid_t pid = pid_tid->first;
2133fe6060f1SDimitry Andric   lldb::tid_t tid = pid_tid->second;
2134fe6060f1SDimitry Andric 
2135fe6060f1SDimitry Andric   if (pid == StringExtractorGDBRemote::AllProcesses)
2136fe6060f1SDimitry Andric     return SendUnimplementedResponse("Selecting all processes not supported");
2137fe6060f1SDimitry Andric   if (pid == LLDB_INVALID_PROCESS_ID)
2138fe6060f1SDimitry Andric     return SendErrorResponse(llvm::make_error<StringError>(
2139fe6060f1SDimitry Andric         inconvertibleErrorCode(), "No current process and no PID provided"));
2140fe6060f1SDimitry Andric 
2141fe6060f1SDimitry Andric   // Check the process ID and find respective process instance.
2142fe6060f1SDimitry Andric   auto new_process_it = m_debugged_processes.find(pid);
2143fe6060f1SDimitry Andric   if (new_process_it == m_debugged_processes.end())
2144fe6060f1SDimitry Andric     return SendErrorResponse(llvm::make_error<StringError>(
2145fe6060f1SDimitry Andric         inconvertibleErrorCode(),
2146fe6060f1SDimitry Andric         llvm::formatv("No process with PID {0} debugged", pid)));
21470b57cec5SDimitry Andric 
21480b57cec5SDimitry Andric   // Ensure we have the given thread when not specifying -1 (all threads) or 0
21490b57cec5SDimitry Andric   // (any thread).
21500b57cec5SDimitry Andric   if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
2151fe6060f1SDimitry Andric     NativeThreadProtocol *thread = new_process_it->second->GetThreadByID(tid);
21520b57cec5SDimitry Andric     if (!thread) {
21539dba64beSDimitry Andric       LLDB_LOGF(log,
21549dba64beSDimitry Andric                 "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
21550b57cec5SDimitry Andric                 " not found",
21560b57cec5SDimitry Andric                 __FUNCTION__, tid);
21570b57cec5SDimitry Andric       return SendErrorResponse(0x15);
21580b57cec5SDimitry Andric     }
21590b57cec5SDimitry Andric   }
21600b57cec5SDimitry Andric 
2161fe6060f1SDimitry Andric   // Now switch the given process and thread type.
21620b57cec5SDimitry Andric   switch (h_variant) {
21630b57cec5SDimitry Andric   case 'g':
2164fe6060f1SDimitry Andric     m_current_process = new_process_it->second.get();
21650b57cec5SDimitry Andric     SetCurrentThreadID(tid);
21660b57cec5SDimitry Andric     break;
21670b57cec5SDimitry Andric 
21680b57cec5SDimitry Andric   case 'c':
2169fe6060f1SDimitry Andric     m_continue_process = new_process_it->second.get();
21700b57cec5SDimitry Andric     SetContinueThreadID(tid);
21710b57cec5SDimitry Andric     break;
21720b57cec5SDimitry Andric 
21730b57cec5SDimitry Andric   default:
21740b57cec5SDimitry Andric     assert(false && "unsupported $H variant - shouldn't get here");
21750b57cec5SDimitry Andric     return SendIllFormedResponse(packet,
21760b57cec5SDimitry Andric                                  "H variant unsupported, should be c or g");
21770b57cec5SDimitry Andric   }
21780b57cec5SDimitry Andric 
21790b57cec5SDimitry Andric   return SendOKResponse();
21800b57cec5SDimitry Andric }
21810b57cec5SDimitry Andric 
21820b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
21830b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) {
21840b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
21850b57cec5SDimitry Andric 
21860b57cec5SDimitry Andric   // Fail if we don't have a current process.
2187fe6060f1SDimitry Andric   if (!m_current_process ||
2188fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
21899dba64beSDimitry Andric     LLDB_LOGF(
21909dba64beSDimitry Andric         log,
21910b57cec5SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
21920b57cec5SDimitry Andric         __FUNCTION__);
21930b57cec5SDimitry Andric     return SendErrorResponse(0x15);
21940b57cec5SDimitry Andric   }
21950b57cec5SDimitry Andric 
21960b57cec5SDimitry Andric   packet.SetFilePos(::strlen("I"));
21970b57cec5SDimitry Andric   uint8_t tmp[4096];
21980b57cec5SDimitry Andric   for (;;) {
21990b57cec5SDimitry Andric     size_t read = packet.GetHexBytesAvail(tmp);
22000b57cec5SDimitry Andric     if (read == 0) {
22010b57cec5SDimitry Andric       break;
22020b57cec5SDimitry Andric     }
22030b57cec5SDimitry Andric     // write directly to stdin *this might block if stdin buffer is full*
22040b57cec5SDimitry Andric     // TODO: enqueue this block in circular buffer and send window size to
22050b57cec5SDimitry Andric     // remote host
22060b57cec5SDimitry Andric     ConnectionStatus status;
22070b57cec5SDimitry Andric     Status error;
22080b57cec5SDimitry Andric     m_stdio_communication.Write(tmp, read, status, &error);
22090b57cec5SDimitry Andric     if (error.Fail()) {
22100b57cec5SDimitry Andric       return SendErrorResponse(0x15);
22110b57cec5SDimitry Andric     }
22120b57cec5SDimitry Andric   }
22130b57cec5SDimitry Andric 
22140b57cec5SDimitry Andric   return SendOKResponse();
22150b57cec5SDimitry Andric }
22160b57cec5SDimitry Andric 
22170b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
22180b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_interrupt(
22190b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
22200b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
22210b57cec5SDimitry Andric 
22220b57cec5SDimitry Andric   // Fail if we don't have a current process.
2223fe6060f1SDimitry Andric   if (!m_current_process ||
2224fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
22250b57cec5SDimitry Andric     LLDB_LOG(log, "failed, no process available");
22260b57cec5SDimitry Andric     return SendErrorResponse(0x15);
22270b57cec5SDimitry Andric   }
22280b57cec5SDimitry Andric 
22290b57cec5SDimitry Andric   // Interrupt the process.
2230fe6060f1SDimitry Andric   Status error = m_current_process->Interrupt();
22310b57cec5SDimitry Andric   if (error.Fail()) {
2232fe6060f1SDimitry Andric     LLDB_LOG(log, "failed for process {0}: {1}", m_current_process->GetID(),
22330b57cec5SDimitry Andric              error);
22340b57cec5SDimitry Andric     return SendErrorResponse(GDBRemoteServerError::eErrorResume);
22350b57cec5SDimitry Andric   }
22360b57cec5SDimitry Andric 
2237fe6060f1SDimitry Andric   LLDB_LOG(log, "stopped process {0}", m_current_process->GetID());
22380b57cec5SDimitry Andric 
22390b57cec5SDimitry Andric   // No response required from stop all.
22400b57cec5SDimitry Andric   return PacketResult::Success;
22410b57cec5SDimitry Andric }
22420b57cec5SDimitry Andric 
22430b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
22440b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_memory_read(
22450b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
22460b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
22470b57cec5SDimitry Andric 
2248fe6060f1SDimitry Andric   if (!m_current_process ||
2249fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
22509dba64beSDimitry Andric     LLDB_LOGF(
22519dba64beSDimitry Andric         log,
22520b57cec5SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
22530b57cec5SDimitry Andric         __FUNCTION__);
22540b57cec5SDimitry Andric     return SendErrorResponse(0x15);
22550b57cec5SDimitry Andric   }
22560b57cec5SDimitry Andric 
22570b57cec5SDimitry Andric   // Parse out the memory address.
22580b57cec5SDimitry Andric   packet.SetFilePos(strlen("m"));
22590b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
22600b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Too short m packet");
22610b57cec5SDimitry Andric 
22620b57cec5SDimitry Andric   // Read the address.  Punting on validation.
22630b57cec5SDimitry Andric   // FIXME replace with Hex U64 read with no default value that fails on failed
22640b57cec5SDimitry Andric   // read.
22650b57cec5SDimitry Andric   const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
22660b57cec5SDimitry Andric 
22670b57cec5SDimitry Andric   // Validate comma.
22680b57cec5SDimitry Andric   if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
22690b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Comma sep missing in m packet");
22700b57cec5SDimitry Andric 
22710b57cec5SDimitry Andric   // Get # bytes to read.
22720b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
22730b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Length missing in m packet");
22740b57cec5SDimitry Andric 
22750b57cec5SDimitry Andric   const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
22760b57cec5SDimitry Andric   if (byte_count == 0) {
22779dba64beSDimitry Andric     LLDB_LOGF(log,
22789dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s nothing to read: "
22790b57cec5SDimitry Andric               "zero-length packet",
22800b57cec5SDimitry Andric               __FUNCTION__);
22810b57cec5SDimitry Andric     return SendOKResponse();
22820b57cec5SDimitry Andric   }
22830b57cec5SDimitry Andric 
22840b57cec5SDimitry Andric   // Allocate the response buffer.
22850b57cec5SDimitry Andric   std::string buf(byte_count, '\0');
22860b57cec5SDimitry Andric   if (buf.empty())
22870b57cec5SDimitry Andric     return SendErrorResponse(0x78);
22880b57cec5SDimitry Andric 
22890b57cec5SDimitry Andric   // Retrieve the process memory.
22900b57cec5SDimitry Andric   size_t bytes_read = 0;
2291fe6060f1SDimitry Andric   Status error = m_current_process->ReadMemoryWithoutTrap(
22920b57cec5SDimitry Andric       read_addr, &buf[0], byte_count, bytes_read);
22930b57cec5SDimitry Andric   if (error.Fail()) {
22949dba64beSDimitry Andric     LLDB_LOGF(log,
22959dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
22960b57cec5SDimitry Andric               " mem 0x%" PRIx64 ": failed to read. Error: %s",
2297fe6060f1SDimitry Andric               __FUNCTION__, m_current_process->GetID(), read_addr,
22980b57cec5SDimitry Andric               error.AsCString());
22990b57cec5SDimitry Andric     return SendErrorResponse(0x08);
23000b57cec5SDimitry Andric   }
23010b57cec5SDimitry Andric 
23020b57cec5SDimitry Andric   if (bytes_read == 0) {
23039dba64beSDimitry Andric     LLDB_LOGF(log,
23049dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
23050b57cec5SDimitry Andric               " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
2306fe6060f1SDimitry Andric               __FUNCTION__, m_current_process->GetID(), read_addr, byte_count);
23070b57cec5SDimitry Andric     return SendErrorResponse(0x08);
23080b57cec5SDimitry Andric   }
23090b57cec5SDimitry Andric 
23100b57cec5SDimitry Andric   StreamGDBRemote response;
23110b57cec5SDimitry Andric   packet.SetFilePos(0);
23120b57cec5SDimitry Andric   char kind = packet.GetChar('?');
23130b57cec5SDimitry Andric   if (kind == 'x')
23140b57cec5SDimitry Andric     response.PutEscapedBytes(buf.data(), byte_count);
23150b57cec5SDimitry Andric   else {
23160b57cec5SDimitry Andric     assert(kind == 'm');
23170b57cec5SDimitry Andric     for (size_t i = 0; i < bytes_read; ++i)
23180b57cec5SDimitry Andric       response.PutHex8(buf[i]);
23190b57cec5SDimitry Andric   }
23200b57cec5SDimitry Andric 
23210b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
23220b57cec5SDimitry Andric }
23230b57cec5SDimitry Andric 
23240b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
2325e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) {
2326e8d8bef9SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
2327e8d8bef9SDimitry Andric 
2328fe6060f1SDimitry Andric   if (!m_current_process ||
2329fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
2330e8d8bef9SDimitry Andric     LLDB_LOGF(
2331e8d8bef9SDimitry Andric         log,
2332e8d8bef9SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
2333e8d8bef9SDimitry Andric         __FUNCTION__);
2334e8d8bef9SDimitry Andric     return SendErrorResponse(0x15);
2335e8d8bef9SDimitry Andric   }
2336e8d8bef9SDimitry Andric 
2337e8d8bef9SDimitry Andric   // Parse out the memory address.
2338e8d8bef9SDimitry Andric   packet.SetFilePos(strlen("_M"));
2339e8d8bef9SDimitry Andric   if (packet.GetBytesLeft() < 1)
2340e8d8bef9SDimitry Andric     return SendIllFormedResponse(packet, "Too short _M packet");
2341e8d8bef9SDimitry Andric 
2342e8d8bef9SDimitry Andric   const lldb::addr_t size = packet.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2343e8d8bef9SDimitry Andric   if (size == LLDB_INVALID_ADDRESS)
2344e8d8bef9SDimitry Andric     return SendIllFormedResponse(packet, "Address not valid");
2345e8d8bef9SDimitry Andric   if (packet.GetChar() != ',')
2346e8d8bef9SDimitry Andric     return SendIllFormedResponse(packet, "Bad packet");
2347e8d8bef9SDimitry Andric   Permissions perms = {};
2348e8d8bef9SDimitry Andric   while (packet.GetBytesLeft() > 0) {
2349e8d8bef9SDimitry Andric     switch (packet.GetChar()) {
2350e8d8bef9SDimitry Andric     case 'r':
2351e8d8bef9SDimitry Andric       perms |= ePermissionsReadable;
2352e8d8bef9SDimitry Andric       break;
2353e8d8bef9SDimitry Andric     case 'w':
2354e8d8bef9SDimitry Andric       perms |= ePermissionsWritable;
2355e8d8bef9SDimitry Andric       break;
2356e8d8bef9SDimitry Andric     case 'x':
2357e8d8bef9SDimitry Andric       perms |= ePermissionsExecutable;
2358e8d8bef9SDimitry Andric       break;
2359e8d8bef9SDimitry Andric     default:
2360e8d8bef9SDimitry Andric       return SendIllFormedResponse(packet, "Bad permissions");
2361e8d8bef9SDimitry Andric     }
2362e8d8bef9SDimitry Andric   }
2363e8d8bef9SDimitry Andric 
2364fe6060f1SDimitry Andric   llvm::Expected<addr_t> addr = m_current_process->AllocateMemory(size, perms);
2365e8d8bef9SDimitry Andric   if (!addr)
2366e8d8bef9SDimitry Andric     return SendErrorResponse(addr.takeError());
2367e8d8bef9SDimitry Andric 
2368e8d8bef9SDimitry Andric   StreamGDBRemote response;
2369e8d8bef9SDimitry Andric   response.PutHex64(*addr);
2370e8d8bef9SDimitry Andric   return SendPacketNoLock(response.GetString());
2371e8d8bef9SDimitry Andric }
2372e8d8bef9SDimitry Andric 
2373e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult
2374e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) {
2375e8d8bef9SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
2376e8d8bef9SDimitry Andric 
2377fe6060f1SDimitry Andric   if (!m_current_process ||
2378fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
2379e8d8bef9SDimitry Andric     LLDB_LOGF(
2380e8d8bef9SDimitry Andric         log,
2381e8d8bef9SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
2382e8d8bef9SDimitry Andric         __FUNCTION__);
2383e8d8bef9SDimitry Andric     return SendErrorResponse(0x15);
2384e8d8bef9SDimitry Andric   }
2385e8d8bef9SDimitry Andric 
2386e8d8bef9SDimitry Andric   // Parse out the memory address.
2387e8d8bef9SDimitry Andric   packet.SetFilePos(strlen("_m"));
2388e8d8bef9SDimitry Andric   if (packet.GetBytesLeft() < 1)
2389e8d8bef9SDimitry Andric     return SendIllFormedResponse(packet, "Too short m packet");
2390e8d8bef9SDimitry Andric 
2391e8d8bef9SDimitry Andric   const lldb::addr_t addr = packet.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
2392e8d8bef9SDimitry Andric   if (addr == LLDB_INVALID_ADDRESS)
2393e8d8bef9SDimitry Andric     return SendIllFormedResponse(packet, "Address not valid");
2394e8d8bef9SDimitry Andric 
2395fe6060f1SDimitry Andric   if (llvm::Error Err = m_current_process->DeallocateMemory(addr))
2396e8d8bef9SDimitry Andric     return SendErrorResponse(std::move(Err));
2397e8d8bef9SDimitry Andric 
2398e8d8bef9SDimitry Andric   return SendOKResponse();
2399e8d8bef9SDimitry Andric }
2400e8d8bef9SDimitry Andric 
2401e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult
24020b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
24030b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
24040b57cec5SDimitry Andric 
2405fe6060f1SDimitry Andric   if (!m_current_process ||
2406fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
24079dba64beSDimitry Andric     LLDB_LOGF(
24089dba64beSDimitry Andric         log,
24090b57cec5SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
24100b57cec5SDimitry Andric         __FUNCTION__);
24110b57cec5SDimitry Andric     return SendErrorResponse(0x15);
24120b57cec5SDimitry Andric   }
24130b57cec5SDimitry Andric 
24140b57cec5SDimitry Andric   // Parse out the memory address.
24150b57cec5SDimitry Andric   packet.SetFilePos(strlen("M"));
24160b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
24170b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Too short M packet");
24180b57cec5SDimitry Andric 
24190b57cec5SDimitry Andric   // Read the address.  Punting on validation.
24200b57cec5SDimitry Andric   // FIXME replace with Hex U64 read with no default value that fails on failed
24210b57cec5SDimitry Andric   // read.
24220b57cec5SDimitry Andric   const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0);
24230b57cec5SDimitry Andric 
24240b57cec5SDimitry Andric   // Validate comma.
24250b57cec5SDimitry Andric   if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
24260b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Comma sep missing in M packet");
24270b57cec5SDimitry Andric 
24280b57cec5SDimitry Andric   // Get # bytes to read.
24290b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
24300b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Length missing in M packet");
24310b57cec5SDimitry Andric 
24320b57cec5SDimitry Andric   const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
24330b57cec5SDimitry Andric   if (byte_count == 0) {
24340b57cec5SDimitry Andric     LLDB_LOG(log, "nothing to write: zero-length packet");
24350b57cec5SDimitry Andric     return PacketResult::Success;
24360b57cec5SDimitry Andric   }
24370b57cec5SDimitry Andric 
24380b57cec5SDimitry Andric   // Validate colon.
24390b57cec5SDimitry Andric   if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':'))
24400b57cec5SDimitry Andric     return SendIllFormedResponse(
24410b57cec5SDimitry Andric         packet, "Comma sep missing in M packet after byte length");
24420b57cec5SDimitry Andric 
24430b57cec5SDimitry Andric   // Allocate the conversion buffer.
24440b57cec5SDimitry Andric   std::vector<uint8_t> buf(byte_count, 0);
24450b57cec5SDimitry Andric   if (buf.empty())
24460b57cec5SDimitry Andric     return SendErrorResponse(0x78);
24470b57cec5SDimitry Andric 
24480b57cec5SDimitry Andric   // Convert the hex memory write contents to bytes.
24490b57cec5SDimitry Andric   StreamGDBRemote response;
24500b57cec5SDimitry Andric   const uint64_t convert_count = packet.GetHexBytes(buf, 0);
24510b57cec5SDimitry Andric   if (convert_count != byte_count) {
24520b57cec5SDimitry Andric     LLDB_LOG(log,
24530b57cec5SDimitry Andric              "pid {0} mem {1:x}: asked to write {2} bytes, but only found {3} "
24540b57cec5SDimitry Andric              "to convert.",
2455fe6060f1SDimitry Andric              m_current_process->GetID(), write_addr, byte_count, convert_count);
24560b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "M content byte length specified did "
24570b57cec5SDimitry Andric                                          "not match hex-encoded content "
24580b57cec5SDimitry Andric                                          "length");
24590b57cec5SDimitry Andric   }
24600b57cec5SDimitry Andric 
24610b57cec5SDimitry Andric   // Write the process memory.
24620b57cec5SDimitry Andric   size_t bytes_written = 0;
2463fe6060f1SDimitry Andric   Status error = m_current_process->WriteMemory(write_addr, &buf[0], byte_count,
2464fe6060f1SDimitry Andric                                                 bytes_written);
24650b57cec5SDimitry Andric   if (error.Fail()) {
24660b57cec5SDimitry Andric     LLDB_LOG(log, "pid {0} mem {1:x}: failed to write. Error: {2}",
2467fe6060f1SDimitry Andric              m_current_process->GetID(), write_addr, error);
24680b57cec5SDimitry Andric     return SendErrorResponse(0x09);
24690b57cec5SDimitry Andric   }
24700b57cec5SDimitry Andric 
24710b57cec5SDimitry Andric   if (bytes_written == 0) {
24720b57cec5SDimitry Andric     LLDB_LOG(log, "pid {0} mem {1:x}: wrote 0 of {2} requested bytes",
2473fe6060f1SDimitry Andric              m_current_process->GetID(), write_addr, byte_count);
24740b57cec5SDimitry Andric     return SendErrorResponse(0x09);
24750b57cec5SDimitry Andric   }
24760b57cec5SDimitry Andric 
24770b57cec5SDimitry Andric   return SendOKResponse();
24780b57cec5SDimitry Andric }
24790b57cec5SDimitry Andric 
24800b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
24810b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
24820b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
24830b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
24840b57cec5SDimitry Andric 
24850b57cec5SDimitry Andric   // Currently only the NativeProcessProtocol knows if it can handle a
24860b57cec5SDimitry Andric   // qMemoryRegionInfoSupported request, but we're not guaranteed to be
24870b57cec5SDimitry Andric   // attached to a process.  For now we'll assume the client only asks this
24880b57cec5SDimitry Andric   // when a process is being debugged.
24890b57cec5SDimitry Andric 
24900b57cec5SDimitry Andric   // Ensure we have a process running; otherwise, we can't figure this out
24910b57cec5SDimitry Andric   // since we won't have a NativeProcessProtocol.
2492fe6060f1SDimitry Andric   if (!m_current_process ||
2493fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
24949dba64beSDimitry Andric     LLDB_LOGF(
24959dba64beSDimitry Andric         log,
24960b57cec5SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
24970b57cec5SDimitry Andric         __FUNCTION__);
24980b57cec5SDimitry Andric     return SendErrorResponse(0x15);
24990b57cec5SDimitry Andric   }
25000b57cec5SDimitry Andric 
25010b57cec5SDimitry Andric   // Test if we can get any region back when asking for the region around NULL.
25020b57cec5SDimitry Andric   MemoryRegionInfo region_info;
2503fe6060f1SDimitry Andric   const Status error = m_current_process->GetMemoryRegionInfo(0, region_info);
25040b57cec5SDimitry Andric   if (error.Fail()) {
25050b57cec5SDimitry Andric     // We don't support memory region info collection for this
25060b57cec5SDimitry Andric     // NativeProcessProtocol.
25070b57cec5SDimitry Andric     return SendUnimplementedResponse("");
25080b57cec5SDimitry Andric   }
25090b57cec5SDimitry Andric 
25100b57cec5SDimitry Andric   return SendOKResponse();
25110b57cec5SDimitry Andric }
25120b57cec5SDimitry Andric 
25130b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
25140b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
25150b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
25160b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
25170b57cec5SDimitry Andric 
25180b57cec5SDimitry Andric   // Ensure we have a process.
2519fe6060f1SDimitry Andric   if (!m_current_process ||
2520fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
25219dba64beSDimitry Andric     LLDB_LOGF(
25229dba64beSDimitry Andric         log,
25230b57cec5SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
25240b57cec5SDimitry Andric         __FUNCTION__);
25250b57cec5SDimitry Andric     return SendErrorResponse(0x15);
25260b57cec5SDimitry Andric   }
25270b57cec5SDimitry Andric 
25280b57cec5SDimitry Andric   // Parse out the memory address.
25290b57cec5SDimitry Andric   packet.SetFilePos(strlen("qMemoryRegionInfo:"));
25300b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
25310b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet");
25320b57cec5SDimitry Andric 
25330b57cec5SDimitry Andric   // Read the address.  Punting on validation.
25340b57cec5SDimitry Andric   const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
25350b57cec5SDimitry Andric 
25360b57cec5SDimitry Andric   StreamGDBRemote response;
25370b57cec5SDimitry Andric 
25380b57cec5SDimitry Andric   // Get the memory region info for the target address.
25390b57cec5SDimitry Andric   MemoryRegionInfo region_info;
25400b57cec5SDimitry Andric   const Status error =
2541fe6060f1SDimitry Andric       m_current_process->GetMemoryRegionInfo(read_addr, region_info);
25420b57cec5SDimitry Andric   if (error.Fail()) {
25430b57cec5SDimitry Andric     // Return the error message.
25440b57cec5SDimitry Andric 
25450b57cec5SDimitry Andric     response.PutCString("error:");
25460b57cec5SDimitry Andric     response.PutStringAsRawHex8(error.AsCString());
25470b57cec5SDimitry Andric     response.PutChar(';');
25480b57cec5SDimitry Andric   } else {
25490b57cec5SDimitry Andric     // Range start and size.
25500b57cec5SDimitry Andric     response.Printf("start:%" PRIx64 ";size:%" PRIx64 ";",
25510b57cec5SDimitry Andric                     region_info.GetRange().GetRangeBase(),
25520b57cec5SDimitry Andric                     region_info.GetRange().GetByteSize());
25530b57cec5SDimitry Andric 
25540b57cec5SDimitry Andric     // Permissions.
25550b57cec5SDimitry Andric     if (region_info.GetReadable() || region_info.GetWritable() ||
25560b57cec5SDimitry Andric         region_info.GetExecutable()) {
25570b57cec5SDimitry Andric       // Write permissions info.
25580b57cec5SDimitry Andric       response.PutCString("permissions:");
25590b57cec5SDimitry Andric 
25600b57cec5SDimitry Andric       if (region_info.GetReadable())
25610b57cec5SDimitry Andric         response.PutChar('r');
25620b57cec5SDimitry Andric       if (region_info.GetWritable())
25630b57cec5SDimitry Andric         response.PutChar('w');
25640b57cec5SDimitry Andric       if (region_info.GetExecutable())
25650b57cec5SDimitry Andric         response.PutChar('x');
25660b57cec5SDimitry Andric 
25670b57cec5SDimitry Andric       response.PutChar(';');
25680b57cec5SDimitry Andric     }
25690b57cec5SDimitry Andric 
2570e8d8bef9SDimitry Andric     // Flags
2571e8d8bef9SDimitry Andric     MemoryRegionInfo::OptionalBool memory_tagged =
2572e8d8bef9SDimitry Andric         region_info.GetMemoryTagged();
2573e8d8bef9SDimitry Andric     if (memory_tagged != MemoryRegionInfo::eDontKnow) {
2574e8d8bef9SDimitry Andric       response.PutCString("flags:");
2575e8d8bef9SDimitry Andric       if (memory_tagged == MemoryRegionInfo::eYes) {
2576e8d8bef9SDimitry Andric         response.PutCString("mt");
2577e8d8bef9SDimitry Andric       }
2578e8d8bef9SDimitry Andric       response.PutChar(';');
2579e8d8bef9SDimitry Andric     }
2580e8d8bef9SDimitry Andric 
25810b57cec5SDimitry Andric     // Name
25820b57cec5SDimitry Andric     ConstString name = region_info.GetName();
25830b57cec5SDimitry Andric     if (name) {
25840b57cec5SDimitry Andric       response.PutCString("name:");
25855ffd83dbSDimitry Andric       response.PutStringAsRawHex8(name.GetStringRef());
25860b57cec5SDimitry Andric       response.PutChar(';');
25870b57cec5SDimitry Andric     }
25880b57cec5SDimitry Andric   }
25890b57cec5SDimitry Andric 
25900b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
25910b57cec5SDimitry Andric }
25920b57cec5SDimitry Andric 
25930b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
25940b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
25950b57cec5SDimitry Andric   // Ensure we have a process.
2596fe6060f1SDimitry Andric   if (!m_current_process ||
2597fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
25980b57cec5SDimitry Andric     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
25990b57cec5SDimitry Andric     LLDB_LOG(log, "failed, no process available");
26000b57cec5SDimitry Andric     return SendErrorResponse(0x15);
26010b57cec5SDimitry Andric   }
26020b57cec5SDimitry Andric 
26030b57cec5SDimitry Andric   // Parse out software or hardware breakpoint or watchpoint requested.
26040b57cec5SDimitry Andric   packet.SetFilePos(strlen("Z"));
26050b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
26060b57cec5SDimitry Andric     return SendIllFormedResponse(
26070b57cec5SDimitry Andric         packet, "Too short Z packet, missing software/hardware specifier");
26080b57cec5SDimitry Andric 
26090b57cec5SDimitry Andric   bool want_breakpoint = true;
26100b57cec5SDimitry Andric   bool want_hardware = false;
26110b57cec5SDimitry Andric   uint32_t watch_flags = 0;
26120b57cec5SDimitry Andric 
26130b57cec5SDimitry Andric   const GDBStoppointType stoppoint_type =
26140b57cec5SDimitry Andric       GDBStoppointType(packet.GetS32(eStoppointInvalid));
26150b57cec5SDimitry Andric   switch (stoppoint_type) {
26160b57cec5SDimitry Andric   case eBreakpointSoftware:
26170b57cec5SDimitry Andric     want_hardware = false;
26180b57cec5SDimitry Andric     want_breakpoint = true;
26190b57cec5SDimitry Andric     break;
26200b57cec5SDimitry Andric   case eBreakpointHardware:
26210b57cec5SDimitry Andric     want_hardware = true;
26220b57cec5SDimitry Andric     want_breakpoint = true;
26230b57cec5SDimitry Andric     break;
26240b57cec5SDimitry Andric   case eWatchpointWrite:
26250b57cec5SDimitry Andric     watch_flags = 1;
26260b57cec5SDimitry Andric     want_hardware = true;
26270b57cec5SDimitry Andric     want_breakpoint = false;
26280b57cec5SDimitry Andric     break;
26290b57cec5SDimitry Andric   case eWatchpointRead:
26300b57cec5SDimitry Andric     watch_flags = 2;
26310b57cec5SDimitry Andric     want_hardware = true;
26320b57cec5SDimitry Andric     want_breakpoint = false;
26330b57cec5SDimitry Andric     break;
26340b57cec5SDimitry Andric   case eWatchpointReadWrite:
26350b57cec5SDimitry Andric     watch_flags = 3;
26360b57cec5SDimitry Andric     want_hardware = true;
26370b57cec5SDimitry Andric     want_breakpoint = false;
26380b57cec5SDimitry Andric     break;
26390b57cec5SDimitry Andric   case eStoppointInvalid:
26400b57cec5SDimitry Andric     return SendIllFormedResponse(
26410b57cec5SDimitry Andric         packet, "Z packet had invalid software/hardware specifier");
26420b57cec5SDimitry Andric   }
26430b57cec5SDimitry Andric 
26440b57cec5SDimitry Andric   if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
26450b57cec5SDimitry Andric     return SendIllFormedResponse(
26460b57cec5SDimitry Andric         packet, "Malformed Z packet, expecting comma after stoppoint type");
26470b57cec5SDimitry Andric 
26480b57cec5SDimitry Andric   // Parse out the stoppoint address.
26490b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
26500b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Too short Z packet, missing address");
26510b57cec5SDimitry Andric   const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
26520b57cec5SDimitry Andric 
26530b57cec5SDimitry Andric   if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
26540b57cec5SDimitry Andric     return SendIllFormedResponse(
26550b57cec5SDimitry Andric         packet, "Malformed Z packet, expecting comma after address");
26560b57cec5SDimitry Andric 
26570b57cec5SDimitry Andric   // Parse out the stoppoint size (i.e. size hint for opcode size).
26580b57cec5SDimitry Andric   const uint32_t size =
26590b57cec5SDimitry Andric       packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
26600b57cec5SDimitry Andric   if (size == std::numeric_limits<uint32_t>::max())
26610b57cec5SDimitry Andric     return SendIllFormedResponse(
26620b57cec5SDimitry Andric         packet, "Malformed Z packet, failed to parse size argument");
26630b57cec5SDimitry Andric 
26640b57cec5SDimitry Andric   if (want_breakpoint) {
26650b57cec5SDimitry Andric     // Try to set the breakpoint.
26660b57cec5SDimitry Andric     const Status error =
2667fe6060f1SDimitry Andric         m_current_process->SetBreakpoint(addr, size, want_hardware);
26680b57cec5SDimitry Andric     if (error.Success())
26690b57cec5SDimitry Andric       return SendOKResponse();
26700b57cec5SDimitry Andric     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
26710b57cec5SDimitry Andric     LLDB_LOG(log, "pid {0} failed to set breakpoint: {1}",
2672fe6060f1SDimitry Andric              m_current_process->GetID(), error);
26730b57cec5SDimitry Andric     return SendErrorResponse(0x09);
26740b57cec5SDimitry Andric   } else {
26750b57cec5SDimitry Andric     // Try to set the watchpoint.
2676fe6060f1SDimitry Andric     const Status error = m_current_process->SetWatchpoint(
26770b57cec5SDimitry Andric         addr, size, watch_flags, want_hardware);
26780b57cec5SDimitry Andric     if (error.Success())
26790b57cec5SDimitry Andric       return SendOKResponse();
26800b57cec5SDimitry Andric     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
26810b57cec5SDimitry Andric     LLDB_LOG(log, "pid {0} failed to set watchpoint: {1}",
2682fe6060f1SDimitry Andric              m_current_process->GetID(), error);
26830b57cec5SDimitry Andric     return SendErrorResponse(0x09);
26840b57cec5SDimitry Andric   }
26850b57cec5SDimitry Andric }
26860b57cec5SDimitry Andric 
26870b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
26880b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
26890b57cec5SDimitry Andric   // Ensure we have a process.
2690fe6060f1SDimitry Andric   if (!m_current_process ||
2691fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
26920b57cec5SDimitry Andric     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
26930b57cec5SDimitry Andric     LLDB_LOG(log, "failed, no process available");
26940b57cec5SDimitry Andric     return SendErrorResponse(0x15);
26950b57cec5SDimitry Andric   }
26960b57cec5SDimitry Andric 
26970b57cec5SDimitry Andric   // Parse out software or hardware breakpoint or watchpoint requested.
26980b57cec5SDimitry Andric   packet.SetFilePos(strlen("z"));
26990b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
27000b57cec5SDimitry Andric     return SendIllFormedResponse(
27010b57cec5SDimitry Andric         packet, "Too short z packet, missing software/hardware specifier");
27020b57cec5SDimitry Andric 
27030b57cec5SDimitry Andric   bool want_breakpoint = true;
27040b57cec5SDimitry Andric   bool want_hardware = false;
27050b57cec5SDimitry Andric 
27060b57cec5SDimitry Andric   const GDBStoppointType stoppoint_type =
27070b57cec5SDimitry Andric       GDBStoppointType(packet.GetS32(eStoppointInvalid));
27080b57cec5SDimitry Andric   switch (stoppoint_type) {
27090b57cec5SDimitry Andric   case eBreakpointHardware:
27100b57cec5SDimitry Andric     want_breakpoint = true;
27110b57cec5SDimitry Andric     want_hardware = true;
27120b57cec5SDimitry Andric     break;
27130b57cec5SDimitry Andric   case eBreakpointSoftware:
27140b57cec5SDimitry Andric     want_breakpoint = true;
27150b57cec5SDimitry Andric     break;
27160b57cec5SDimitry Andric   case eWatchpointWrite:
27170b57cec5SDimitry Andric     want_breakpoint = false;
27180b57cec5SDimitry Andric     break;
27190b57cec5SDimitry Andric   case eWatchpointRead:
27200b57cec5SDimitry Andric     want_breakpoint = false;
27210b57cec5SDimitry Andric     break;
27220b57cec5SDimitry Andric   case eWatchpointReadWrite:
27230b57cec5SDimitry Andric     want_breakpoint = false;
27240b57cec5SDimitry Andric     break;
27250b57cec5SDimitry Andric   default:
27260b57cec5SDimitry Andric     return SendIllFormedResponse(
27270b57cec5SDimitry Andric         packet, "z packet had invalid software/hardware specifier");
27280b57cec5SDimitry Andric   }
27290b57cec5SDimitry Andric 
27300b57cec5SDimitry Andric   if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
27310b57cec5SDimitry Andric     return SendIllFormedResponse(
27320b57cec5SDimitry Andric         packet, "Malformed z packet, expecting comma after stoppoint type");
27330b57cec5SDimitry Andric 
27340b57cec5SDimitry Andric   // Parse out the stoppoint address.
27350b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
27360b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "Too short z packet, missing address");
27370b57cec5SDimitry Andric   const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
27380b57cec5SDimitry Andric 
27390b57cec5SDimitry Andric   if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
27400b57cec5SDimitry Andric     return SendIllFormedResponse(
27410b57cec5SDimitry Andric         packet, "Malformed z packet, expecting comma after address");
27420b57cec5SDimitry Andric 
27430b57cec5SDimitry Andric   /*
27440b57cec5SDimitry Andric   // Parse out the stoppoint size (i.e. size hint for opcode size).
27450b57cec5SDimitry Andric   const uint32_t size = packet.GetHexMaxU32 (false,
27460b57cec5SDimitry Andric   std::numeric_limits<uint32_t>::max ());
27470b57cec5SDimitry Andric   if (size == std::numeric_limits<uint32_t>::max ())
27480b57cec5SDimitry Andric       return SendIllFormedResponse(packet, "Malformed z packet, failed to parse
27490b57cec5SDimitry Andric   size argument");
27500b57cec5SDimitry Andric   */
27510b57cec5SDimitry Andric 
27520b57cec5SDimitry Andric   if (want_breakpoint) {
27530b57cec5SDimitry Andric     // Try to clear the breakpoint.
27540b57cec5SDimitry Andric     const Status error =
2755fe6060f1SDimitry Andric         m_current_process->RemoveBreakpoint(addr, want_hardware);
27560b57cec5SDimitry Andric     if (error.Success())
27570b57cec5SDimitry Andric       return SendOKResponse();
27580b57cec5SDimitry Andric     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
27590b57cec5SDimitry Andric     LLDB_LOG(log, "pid {0} failed to remove breakpoint: {1}",
2760fe6060f1SDimitry Andric              m_current_process->GetID(), error);
27610b57cec5SDimitry Andric     return SendErrorResponse(0x09);
27620b57cec5SDimitry Andric   } else {
27630b57cec5SDimitry Andric     // Try to clear the watchpoint.
2764fe6060f1SDimitry Andric     const Status error = m_current_process->RemoveWatchpoint(addr);
27650b57cec5SDimitry Andric     if (error.Success())
27660b57cec5SDimitry Andric       return SendOKResponse();
27670b57cec5SDimitry Andric     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
27680b57cec5SDimitry Andric     LLDB_LOG(log, "pid {0} failed to remove watchpoint: {1}",
2769fe6060f1SDimitry Andric              m_current_process->GetID(), error);
27700b57cec5SDimitry Andric     return SendErrorResponse(0x09);
27710b57cec5SDimitry Andric   }
27720b57cec5SDimitry Andric }
27730b57cec5SDimitry Andric 
27740b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
27750b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
27760b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
27770b57cec5SDimitry Andric 
27780b57cec5SDimitry Andric   // Ensure we have a process.
2779fe6060f1SDimitry Andric   if (!m_continue_process ||
2780fe6060f1SDimitry Andric       (m_continue_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
27819dba64beSDimitry Andric     LLDB_LOGF(
27829dba64beSDimitry Andric         log,
27830b57cec5SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
27840b57cec5SDimitry Andric         __FUNCTION__);
27850b57cec5SDimitry Andric     return SendErrorResponse(0x32);
27860b57cec5SDimitry Andric   }
27870b57cec5SDimitry Andric 
27880b57cec5SDimitry Andric   // We first try to use a continue thread id.  If any one or any all set, use
27890b57cec5SDimitry Andric   // the current thread. Bail out if we don't have a thread id.
27900b57cec5SDimitry Andric   lldb::tid_t tid = GetContinueThreadID();
27910b57cec5SDimitry Andric   if (tid == 0 || tid == LLDB_INVALID_THREAD_ID)
27920b57cec5SDimitry Andric     tid = GetCurrentThreadID();
27930b57cec5SDimitry Andric   if (tid == LLDB_INVALID_THREAD_ID)
27940b57cec5SDimitry Andric     return SendErrorResponse(0x33);
27950b57cec5SDimitry Andric 
27960b57cec5SDimitry Andric   // Double check that we have such a thread.
27970b57cec5SDimitry Andric   // TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
2798fe6060f1SDimitry Andric   NativeThreadProtocol *thread = m_continue_process->GetThreadByID(tid);
27990b57cec5SDimitry Andric   if (!thread)
28000b57cec5SDimitry Andric     return SendErrorResponse(0x33);
28010b57cec5SDimitry Andric 
28020b57cec5SDimitry Andric   // Create the step action for the given thread.
28039dba64beSDimitry Andric   ResumeAction action = {tid, eStateStepping, LLDB_INVALID_SIGNAL_NUMBER};
28040b57cec5SDimitry Andric 
28050b57cec5SDimitry Andric   // Setup the actions list.
28060b57cec5SDimitry Andric   ResumeActionList actions;
28070b57cec5SDimitry Andric   actions.Append(action);
28080b57cec5SDimitry Andric 
28090b57cec5SDimitry Andric   // All other threads stop while we're single stepping a thread.
28100b57cec5SDimitry Andric   actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
2811fe6060f1SDimitry Andric   Status error = m_continue_process->Resume(actions);
28120b57cec5SDimitry Andric   if (error.Fail()) {
28139dba64beSDimitry Andric     LLDB_LOGF(log,
28149dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
28150b57cec5SDimitry Andric               " tid %" PRIu64 " Resume() failed with error: %s",
2816fe6060f1SDimitry Andric               __FUNCTION__, m_continue_process->GetID(), tid,
28170b57cec5SDimitry Andric               error.AsCString());
28180b57cec5SDimitry Andric     return SendErrorResponse(0x49);
28190b57cec5SDimitry Andric   }
28200b57cec5SDimitry Andric 
28210b57cec5SDimitry Andric   // No response here - the stop or exit will come from the resulting action.
28220b57cec5SDimitry Andric   return PacketResult::Success;
28230b57cec5SDimitry Andric }
28240b57cec5SDimitry Andric 
28250b57cec5SDimitry Andric llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
28265ffd83dbSDimitry Andric GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
28275ffd83dbSDimitry Andric   // Ensure we have a thread.
2828fe6060f1SDimitry Andric   NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0);
28295ffd83dbSDimitry Andric   if (!thread)
28305ffd83dbSDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
28315ffd83dbSDimitry Andric                                    "No thread available");
28325ffd83dbSDimitry Andric 
28335ffd83dbSDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
28345ffd83dbSDimitry Andric   // Get the register context for the first thread.
28355ffd83dbSDimitry Andric   NativeRegisterContext &reg_context = thread->GetRegisterContext();
28365ffd83dbSDimitry Andric 
28375ffd83dbSDimitry Andric   StreamString response;
28385ffd83dbSDimitry Andric 
28395ffd83dbSDimitry Andric   response.Printf("<?xml version=\"1.0\"?>");
28405ffd83dbSDimitry Andric   response.Printf("<target version=\"1.0\">");
28415ffd83dbSDimitry Andric 
28425ffd83dbSDimitry Andric   response.Printf("<architecture>%s</architecture>",
2843fe6060f1SDimitry Andric                   m_current_process->GetArchitecture()
28445ffd83dbSDimitry Andric                       .GetTriple()
28455ffd83dbSDimitry Andric                       .getArchName()
28465ffd83dbSDimitry Andric                       .str()
28475ffd83dbSDimitry Andric                       .c_str());
28485ffd83dbSDimitry Andric 
28495ffd83dbSDimitry Andric   response.Printf("<feature>");
28505ffd83dbSDimitry Andric 
28515ffd83dbSDimitry Andric   const int registers_count = reg_context.GetUserRegisterCount();
28525ffd83dbSDimitry Andric   for (int reg_index = 0; reg_index < registers_count; reg_index++) {
28535ffd83dbSDimitry Andric     const RegisterInfo *reg_info =
28545ffd83dbSDimitry Andric         reg_context.GetRegisterInfoAtIndex(reg_index);
28555ffd83dbSDimitry Andric 
28565ffd83dbSDimitry Andric     if (!reg_info) {
28575ffd83dbSDimitry Andric       LLDB_LOGF(log,
28585ffd83dbSDimitry Andric                 "%s failed to get register info for register index %" PRIu32,
28595ffd83dbSDimitry Andric                 "target.xml", reg_index);
28605ffd83dbSDimitry Andric       continue;
28615ffd83dbSDimitry Andric     }
28625ffd83dbSDimitry Andric 
2863e8d8bef9SDimitry Andric     response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" regnum=\"%d\" ",
2864e8d8bef9SDimitry Andric                     reg_info->name, reg_info->byte_size * 8, reg_index);
2865e8d8bef9SDimitry Andric 
2866e8d8bef9SDimitry Andric     if (!reg_context.RegisterOffsetIsDynamic())
2867e8d8bef9SDimitry Andric       response.Printf("offset=\"%" PRIu32 "\" ", reg_info->byte_offset);
28685ffd83dbSDimitry Andric 
28695ffd83dbSDimitry Andric     if (reg_info->alt_name && reg_info->alt_name[0])
28705ffd83dbSDimitry Andric       response.Printf("altname=\"%s\" ", reg_info->alt_name);
28715ffd83dbSDimitry Andric 
28725ffd83dbSDimitry Andric     llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info);
28735ffd83dbSDimitry Andric     if (!encoding.empty())
28745ffd83dbSDimitry Andric       response << "encoding=\"" << encoding << "\" ";
28755ffd83dbSDimitry Andric 
28765ffd83dbSDimitry Andric     llvm::StringRef format = GetFormatNameOrEmpty(*reg_info);
28775ffd83dbSDimitry Andric     if (!format.empty())
28785ffd83dbSDimitry Andric       response << "format=\"" << format << "\" ";
28795ffd83dbSDimitry Andric 
28805ffd83dbSDimitry Andric     const char *const register_set_name =
28815ffd83dbSDimitry Andric         reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
28825ffd83dbSDimitry Andric     if (register_set_name)
28835ffd83dbSDimitry Andric       response << "group=\"" << register_set_name << "\" ";
28845ffd83dbSDimitry Andric 
28855ffd83dbSDimitry Andric     if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] !=
28865ffd83dbSDimitry Andric         LLDB_INVALID_REGNUM)
28875ffd83dbSDimitry Andric       response.Printf("ehframe_regnum=\"%" PRIu32 "\" ",
28885ffd83dbSDimitry Andric                       reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
28895ffd83dbSDimitry Andric 
28905ffd83dbSDimitry Andric     if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] !=
28915ffd83dbSDimitry Andric         LLDB_INVALID_REGNUM)
28925ffd83dbSDimitry Andric       response.Printf("dwarf_regnum=\"%" PRIu32 "\" ",
28935ffd83dbSDimitry Andric                       reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
28945ffd83dbSDimitry Andric 
28955ffd83dbSDimitry Andric     llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info);
28965ffd83dbSDimitry Andric     if (!kind_generic.empty())
28975ffd83dbSDimitry Andric       response << "generic=\"" << kind_generic << "\" ";
28985ffd83dbSDimitry Andric 
28995ffd83dbSDimitry Andric     if (reg_info->value_regs &&
29005ffd83dbSDimitry Andric         reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
29015ffd83dbSDimitry Andric       response.PutCString("value_regnums=\"");
29025ffd83dbSDimitry Andric       CollectRegNums(reg_info->value_regs, response, false);
29035ffd83dbSDimitry Andric       response.Printf("\" ");
29045ffd83dbSDimitry Andric     }
29055ffd83dbSDimitry Andric 
29065ffd83dbSDimitry Andric     if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) {
29075ffd83dbSDimitry Andric       response.PutCString("invalidate_regnums=\"");
29085ffd83dbSDimitry Andric       CollectRegNums(reg_info->invalidate_regs, response, false);
29095ffd83dbSDimitry Andric       response.Printf("\" ");
29105ffd83dbSDimitry Andric     }
29115ffd83dbSDimitry Andric 
29125ffd83dbSDimitry Andric     if (reg_info->dynamic_size_dwarf_expr_bytes) {
29135ffd83dbSDimitry Andric       const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
29145ffd83dbSDimitry Andric       response.PutCString("dynamic_size_dwarf_expr_bytes=\"");
29155ffd83dbSDimitry Andric       for (uint32_t i = 0; i < dwarf_opcode_len; ++i)
29165ffd83dbSDimitry Andric         response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]);
29175ffd83dbSDimitry Andric       response.Printf("\" ");
29185ffd83dbSDimitry Andric     }
29195ffd83dbSDimitry Andric 
29205ffd83dbSDimitry Andric     response.Printf("/>");
29215ffd83dbSDimitry Andric   }
29225ffd83dbSDimitry Andric 
29235ffd83dbSDimitry Andric   response.Printf("</feature>");
29245ffd83dbSDimitry Andric   response.Printf("</target>");
29255ffd83dbSDimitry Andric   return MemoryBuffer::getMemBufferCopy(response.GetString(), "target.xml");
29265ffd83dbSDimitry Andric }
29275ffd83dbSDimitry Andric 
29285ffd83dbSDimitry Andric llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
29290b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
29300b57cec5SDimitry Andric                                                  llvm::StringRef annex) {
29310b57cec5SDimitry Andric   // Make sure we have a valid process.
2932fe6060f1SDimitry Andric   if (!m_current_process ||
2933fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
29340b57cec5SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
29350b57cec5SDimitry Andric                                    "No process available");
29360b57cec5SDimitry Andric   }
29370b57cec5SDimitry Andric 
29385ffd83dbSDimitry Andric   if (object == "auxv") {
29390b57cec5SDimitry Andric     // Grab the auxv data.
2940fe6060f1SDimitry Andric     auto buffer_or_error = m_current_process->GetAuxvData();
29410b57cec5SDimitry Andric     if (!buffer_or_error)
29420b57cec5SDimitry Andric       return llvm::errorCodeToError(buffer_or_error.getError());
29430b57cec5SDimitry Andric     return std::move(*buffer_or_error);
29440b57cec5SDimitry Andric   }
29450b57cec5SDimitry Andric 
29469dba64beSDimitry Andric   if (object == "libraries-svr4") {
2947fe6060f1SDimitry Andric     auto library_list = m_current_process->GetLoadedSVR4Libraries();
29489dba64beSDimitry Andric     if (!library_list)
29499dba64beSDimitry Andric       return library_list.takeError();
29509dba64beSDimitry Andric 
29519dba64beSDimitry Andric     StreamString response;
29529dba64beSDimitry Andric     response.Printf("<library-list-svr4 version=\"1.0\">");
29539dba64beSDimitry Andric     for (auto const &library : *library_list) {
29549dba64beSDimitry Andric       response.Printf("<library name=\"%s\" ",
29559dba64beSDimitry Andric                       XMLEncodeAttributeValue(library.name.c_str()).c_str());
29569dba64beSDimitry Andric       response.Printf("lm=\"0x%" PRIx64 "\" ", library.link_map);
29579dba64beSDimitry Andric       response.Printf("l_addr=\"0x%" PRIx64 "\" ", library.base_addr);
29589dba64beSDimitry Andric       response.Printf("l_ld=\"0x%" PRIx64 "\" />", library.ld_addr);
29599dba64beSDimitry Andric     }
29609dba64beSDimitry Andric     response.Printf("</library-list-svr4>");
29619dba64beSDimitry Andric     return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__);
29629dba64beSDimitry Andric   }
29639dba64beSDimitry Andric 
29645ffd83dbSDimitry Andric   if (object == "features" && annex == "target.xml")
29655ffd83dbSDimitry Andric     return BuildTargetXml();
29665ffd83dbSDimitry Andric 
2967e8d8bef9SDimitry Andric   return llvm::make_error<UnimplementedError>();
29680b57cec5SDimitry Andric }
29690b57cec5SDimitry Andric 
29700b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
29710b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qXfer(
29720b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
29730b57cec5SDimitry Andric   SmallVector<StringRef, 5> fields;
29740b57cec5SDimitry Andric   // The packet format is "qXfer:<object>:<action>:<annex>:offset,length"
29750b57cec5SDimitry Andric   StringRef(packet.GetStringRef()).split(fields, ':', 4);
29760b57cec5SDimitry Andric   if (fields.size() != 5)
29770b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "malformed qXfer packet");
29780b57cec5SDimitry Andric   StringRef &xfer_object = fields[1];
29790b57cec5SDimitry Andric   StringRef &xfer_action = fields[2];
29800b57cec5SDimitry Andric   StringRef &xfer_annex = fields[3];
29810b57cec5SDimitry Andric   StringExtractor offset_data(fields[4]);
29820b57cec5SDimitry Andric   if (xfer_action != "read")
29830b57cec5SDimitry Andric     return SendUnimplementedResponse("qXfer action not supported");
29840b57cec5SDimitry Andric   // Parse offset.
29850b57cec5SDimitry Andric   const uint64_t xfer_offset =
29860b57cec5SDimitry Andric       offset_data.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
29870b57cec5SDimitry Andric   if (xfer_offset == std::numeric_limits<uint64_t>::max())
29880b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "qXfer packet missing offset");
29890b57cec5SDimitry Andric   // Parse out comma.
29900b57cec5SDimitry Andric   if (offset_data.GetChar() != ',')
29910b57cec5SDimitry Andric     return SendIllFormedResponse(packet,
29920b57cec5SDimitry Andric                                  "qXfer packet missing comma after offset");
29930b57cec5SDimitry Andric   // Parse out the length.
29940b57cec5SDimitry Andric   const uint64_t xfer_length =
29950b57cec5SDimitry Andric       offset_data.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
29960b57cec5SDimitry Andric   if (xfer_length == std::numeric_limits<uint64_t>::max())
29970b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "qXfer packet missing length");
29980b57cec5SDimitry Andric 
29990b57cec5SDimitry Andric   // Get a previously constructed buffer if it exists or create it now.
30000b57cec5SDimitry Andric   std::string buffer_key = (xfer_object + xfer_action + xfer_annex).str();
30010b57cec5SDimitry Andric   auto buffer_it = m_xfer_buffer_map.find(buffer_key);
30020b57cec5SDimitry Andric   if (buffer_it == m_xfer_buffer_map.end()) {
30030b57cec5SDimitry Andric     auto buffer_up = ReadXferObject(xfer_object, xfer_annex);
30040b57cec5SDimitry Andric     if (!buffer_up)
30050b57cec5SDimitry Andric       return SendErrorResponse(buffer_up.takeError());
30060b57cec5SDimitry Andric     buffer_it = m_xfer_buffer_map
30070b57cec5SDimitry Andric                     .insert(std::make_pair(buffer_key, std::move(*buffer_up)))
30080b57cec5SDimitry Andric                     .first;
30090b57cec5SDimitry Andric   }
30100b57cec5SDimitry Andric 
30110b57cec5SDimitry Andric   // Send back the response
30120b57cec5SDimitry Andric   StreamGDBRemote response;
30130b57cec5SDimitry Andric   bool done_with_buffer = false;
30140b57cec5SDimitry Andric   llvm::StringRef buffer = buffer_it->second->getBuffer();
30150b57cec5SDimitry Andric   if (xfer_offset >= buffer.size()) {
30160b57cec5SDimitry Andric     // We have nothing left to send.  Mark the buffer as complete.
30170b57cec5SDimitry Andric     response.PutChar('l');
30180b57cec5SDimitry Andric     done_with_buffer = true;
30190b57cec5SDimitry Andric   } else {
30200b57cec5SDimitry Andric     // Figure out how many bytes are available starting at the given offset.
30210b57cec5SDimitry Andric     buffer = buffer.drop_front(xfer_offset);
30220b57cec5SDimitry Andric     // Mark the response type according to whether we're reading the remainder
30230b57cec5SDimitry Andric     // of the data.
30240b57cec5SDimitry Andric     if (xfer_length >= buffer.size()) {
30250b57cec5SDimitry Andric       // There will be nothing left to read after this
30260b57cec5SDimitry Andric       response.PutChar('l');
30270b57cec5SDimitry Andric       done_with_buffer = true;
30280b57cec5SDimitry Andric     } else {
30290b57cec5SDimitry Andric       // There will still be bytes to read after this request.
30300b57cec5SDimitry Andric       response.PutChar('m');
30310b57cec5SDimitry Andric       buffer = buffer.take_front(xfer_length);
30320b57cec5SDimitry Andric     }
30330b57cec5SDimitry Andric     // Now write the data in encoded binary form.
30340b57cec5SDimitry Andric     response.PutEscapedBytes(buffer.data(), buffer.size());
30350b57cec5SDimitry Andric   }
30360b57cec5SDimitry Andric 
30370b57cec5SDimitry Andric   if (done_with_buffer)
30380b57cec5SDimitry Andric     m_xfer_buffer_map.erase(buffer_it);
30390b57cec5SDimitry Andric 
30400b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
30410b57cec5SDimitry Andric }
30420b57cec5SDimitry Andric 
30430b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
30440b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
30450b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
30460b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
30470b57cec5SDimitry Andric 
30480b57cec5SDimitry Andric   // Move past packet name.
30490b57cec5SDimitry Andric   packet.SetFilePos(strlen("QSaveRegisterState"));
30500b57cec5SDimitry Andric 
30510b57cec5SDimitry Andric   // Get the thread to use.
30520b57cec5SDimitry Andric   NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
30530b57cec5SDimitry Andric   if (!thread) {
30540b57cec5SDimitry Andric     if (m_thread_suffix_supported)
30550b57cec5SDimitry Andric       return SendIllFormedResponse(
30560b57cec5SDimitry Andric           packet, "No thread specified in QSaveRegisterState packet");
30570b57cec5SDimitry Andric     else
30580b57cec5SDimitry Andric       return SendIllFormedResponse(packet,
30590b57cec5SDimitry Andric                                    "No thread was is set with the Hg packet");
30600b57cec5SDimitry Andric   }
30610b57cec5SDimitry Andric 
30620b57cec5SDimitry Andric   // Grab the register context for the thread.
30630b57cec5SDimitry Andric   NativeRegisterContext& reg_context = thread->GetRegisterContext();
30640b57cec5SDimitry Andric 
30650b57cec5SDimitry Andric   // Save registers to a buffer.
30660b57cec5SDimitry Andric   DataBufferSP register_data_sp;
30670b57cec5SDimitry Andric   Status error = reg_context.ReadAllRegisterValues(register_data_sp);
30680b57cec5SDimitry Andric   if (error.Fail()) {
30690b57cec5SDimitry Andric     LLDB_LOG(log, "pid {0} failed to save all register values: {1}",
3070fe6060f1SDimitry Andric              m_current_process->GetID(), error);
30710b57cec5SDimitry Andric     return SendErrorResponse(0x75);
30720b57cec5SDimitry Andric   }
30730b57cec5SDimitry Andric 
30740b57cec5SDimitry Andric   // Allocate a new save id.
30750b57cec5SDimitry Andric   const uint32_t save_id = GetNextSavedRegistersID();
30760b57cec5SDimitry Andric   assert((m_saved_registers_map.find(save_id) == m_saved_registers_map.end()) &&
30770b57cec5SDimitry Andric          "GetNextRegisterSaveID() returned an existing register save id");
30780b57cec5SDimitry Andric 
30790b57cec5SDimitry Andric   // Save the register data buffer under the save id.
30800b57cec5SDimitry Andric   {
30810b57cec5SDimitry Andric     std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
30820b57cec5SDimitry Andric     m_saved_registers_map[save_id] = register_data_sp;
30830b57cec5SDimitry Andric   }
30840b57cec5SDimitry Andric 
30850b57cec5SDimitry Andric   // Write the response.
30860b57cec5SDimitry Andric   StreamGDBRemote response;
30870b57cec5SDimitry Andric   response.Printf("%" PRIu32, save_id);
30880b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
30890b57cec5SDimitry Andric }
30900b57cec5SDimitry Andric 
30910b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
30920b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
30930b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
30940b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
30950b57cec5SDimitry Andric 
30960b57cec5SDimitry Andric   // Parse out save id.
30970b57cec5SDimitry Andric   packet.SetFilePos(strlen("QRestoreRegisterState:"));
30980b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1)
30990b57cec5SDimitry Andric     return SendIllFormedResponse(
31000b57cec5SDimitry Andric         packet, "QRestoreRegisterState packet missing register save id");
31010b57cec5SDimitry Andric 
31020b57cec5SDimitry Andric   const uint32_t save_id = packet.GetU32(0);
31030b57cec5SDimitry Andric   if (save_id == 0) {
31040b57cec5SDimitry Andric     LLDB_LOG(log, "QRestoreRegisterState packet has malformed save id, "
31050b57cec5SDimitry Andric                   "expecting decimal uint32_t");
31060b57cec5SDimitry Andric     return SendErrorResponse(0x76);
31070b57cec5SDimitry Andric   }
31080b57cec5SDimitry Andric 
31090b57cec5SDimitry Andric   // Get the thread to use.
31100b57cec5SDimitry Andric   NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
31110b57cec5SDimitry Andric   if (!thread) {
31120b57cec5SDimitry Andric     if (m_thread_suffix_supported)
31130b57cec5SDimitry Andric       return SendIllFormedResponse(
31140b57cec5SDimitry Andric           packet, "No thread specified in QRestoreRegisterState packet");
31150b57cec5SDimitry Andric     else
31160b57cec5SDimitry Andric       return SendIllFormedResponse(packet,
31170b57cec5SDimitry Andric                                    "No thread was is set with the Hg packet");
31180b57cec5SDimitry Andric   }
31190b57cec5SDimitry Andric 
31200b57cec5SDimitry Andric   // Grab the register context for the thread.
31210b57cec5SDimitry Andric   NativeRegisterContext &reg_context = thread->GetRegisterContext();
31220b57cec5SDimitry Andric 
31230b57cec5SDimitry Andric   // Retrieve register state buffer, then remove from the list.
31240b57cec5SDimitry Andric   DataBufferSP register_data_sp;
31250b57cec5SDimitry Andric   {
31260b57cec5SDimitry Andric     std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
31270b57cec5SDimitry Andric 
31280b57cec5SDimitry Andric     // Find the register set buffer for the given save id.
31290b57cec5SDimitry Andric     auto it = m_saved_registers_map.find(save_id);
31300b57cec5SDimitry Andric     if (it == m_saved_registers_map.end()) {
31310b57cec5SDimitry Andric       LLDB_LOG(log,
31320b57cec5SDimitry Andric                "pid {0} does not have a register set save buffer for id {1}",
3133fe6060f1SDimitry Andric                m_current_process->GetID(), save_id);
31340b57cec5SDimitry Andric       return SendErrorResponse(0x77);
31350b57cec5SDimitry Andric     }
31360b57cec5SDimitry Andric     register_data_sp = it->second;
31370b57cec5SDimitry Andric 
31380b57cec5SDimitry Andric     // Remove it from the map.
31390b57cec5SDimitry Andric     m_saved_registers_map.erase(it);
31400b57cec5SDimitry Andric   }
31410b57cec5SDimitry Andric 
31420b57cec5SDimitry Andric   Status error = reg_context.WriteAllRegisterValues(register_data_sp);
31430b57cec5SDimitry Andric   if (error.Fail()) {
31440b57cec5SDimitry Andric     LLDB_LOG(log, "pid {0} failed to restore all register values: {1}",
3145fe6060f1SDimitry Andric              m_current_process->GetID(), error);
31460b57cec5SDimitry Andric     return SendErrorResponse(0x77);
31470b57cec5SDimitry Andric   }
31480b57cec5SDimitry Andric 
31490b57cec5SDimitry Andric   return SendOKResponse();
31500b57cec5SDimitry Andric }
31510b57cec5SDimitry Andric 
31520b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
31530b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vAttach(
31540b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
31550b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
31560b57cec5SDimitry Andric 
31570b57cec5SDimitry Andric   // Consume the ';' after vAttach.
31580b57cec5SDimitry Andric   packet.SetFilePos(strlen("vAttach"));
31590b57cec5SDimitry Andric   if (!packet.GetBytesLeft() || packet.GetChar() != ';')
31600b57cec5SDimitry Andric     return SendIllFormedResponse(packet, "vAttach missing expected ';'");
31610b57cec5SDimitry Andric 
31620b57cec5SDimitry Andric   // Grab the PID to which we will attach (assume hex encoding).
31630b57cec5SDimitry Andric   lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16);
31640b57cec5SDimitry Andric   if (pid == LLDB_INVALID_PROCESS_ID)
31650b57cec5SDimitry Andric     return SendIllFormedResponse(packet,
31660b57cec5SDimitry Andric                                  "vAttach failed to parse the process id");
31670b57cec5SDimitry Andric 
31680b57cec5SDimitry Andric   // Attempt to attach.
31699dba64beSDimitry Andric   LLDB_LOGF(log,
31709dba64beSDimitry Andric             "GDBRemoteCommunicationServerLLGS::%s attempting to attach to "
31710b57cec5SDimitry Andric             "pid %" PRIu64,
31720b57cec5SDimitry Andric             __FUNCTION__, pid);
31730b57cec5SDimitry Andric 
31740b57cec5SDimitry Andric   Status error = AttachToProcess(pid);
31750b57cec5SDimitry Andric 
31760b57cec5SDimitry Andric   if (error.Fail()) {
31779dba64beSDimitry Andric     LLDB_LOGF(log,
31789dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed to attach to "
31790b57cec5SDimitry Andric               "pid %" PRIu64 ": %s\n",
31800b57cec5SDimitry Andric               __FUNCTION__, pid, error.AsCString());
31810b57cec5SDimitry Andric     return SendErrorResponse(error);
31820b57cec5SDimitry Andric   }
31830b57cec5SDimitry Andric 
31840b57cec5SDimitry Andric   // Notify we attached by sending a stop packet.
3185fe6060f1SDimitry Andric   return SendStopReasonForState(m_current_process->GetState());
31860b57cec5SDimitry Andric }
31870b57cec5SDimitry Andric 
31880b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
3189e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vAttachWait(
3190e8d8bef9SDimitry Andric     StringExtractorGDBRemote &packet) {
3191e8d8bef9SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
3192e8d8bef9SDimitry Andric 
3193e8d8bef9SDimitry Andric   // Consume the ';' after the identifier.
3194e8d8bef9SDimitry Andric   packet.SetFilePos(strlen("vAttachWait"));
3195e8d8bef9SDimitry Andric 
3196e8d8bef9SDimitry Andric   if (!packet.GetBytesLeft() || packet.GetChar() != ';')
3197e8d8bef9SDimitry Andric     return SendIllFormedResponse(packet, "vAttachWait missing expected ';'");
3198e8d8bef9SDimitry Andric 
3199e8d8bef9SDimitry Andric   // Allocate the buffer for the process name from vAttachWait.
3200e8d8bef9SDimitry Andric   std::string process_name;
3201e8d8bef9SDimitry Andric   if (!packet.GetHexByteString(process_name))
3202e8d8bef9SDimitry Andric     return SendIllFormedResponse(packet,
3203e8d8bef9SDimitry Andric                                  "vAttachWait failed to parse process name");
3204e8d8bef9SDimitry Andric 
3205e8d8bef9SDimitry Andric   LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name);
3206e8d8bef9SDimitry Andric 
3207e8d8bef9SDimitry Andric   Status error = AttachWaitProcess(process_name, false);
3208e8d8bef9SDimitry Andric   if (error.Fail()) {
3209e8d8bef9SDimitry Andric     LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name,
3210e8d8bef9SDimitry Andric              error);
3211e8d8bef9SDimitry Andric     return SendErrorResponse(error);
3212e8d8bef9SDimitry Andric   }
3213e8d8bef9SDimitry Andric 
3214e8d8bef9SDimitry Andric   // Notify we attached by sending a stop packet.
3215fe6060f1SDimitry Andric   return SendStopReasonForState(m_current_process->GetState());
3216e8d8bef9SDimitry Andric }
3217e8d8bef9SDimitry Andric 
3218e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult
3219e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported(
3220e8d8bef9SDimitry Andric     StringExtractorGDBRemote &packet) {
3221e8d8bef9SDimitry Andric   return SendOKResponse();
3222e8d8bef9SDimitry Andric }
3223e8d8bef9SDimitry Andric 
3224e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult
3225e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait(
3226e8d8bef9SDimitry Andric     StringExtractorGDBRemote &packet) {
3227e8d8bef9SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
3228e8d8bef9SDimitry Andric 
3229e8d8bef9SDimitry Andric   // Consume the ';' after the identifier.
3230e8d8bef9SDimitry Andric   packet.SetFilePos(strlen("vAttachOrWait"));
3231e8d8bef9SDimitry Andric 
3232e8d8bef9SDimitry Andric   if (!packet.GetBytesLeft() || packet.GetChar() != ';')
3233e8d8bef9SDimitry Andric     return SendIllFormedResponse(packet, "vAttachOrWait missing expected ';'");
3234e8d8bef9SDimitry Andric 
3235e8d8bef9SDimitry Andric   // Allocate the buffer for the process name from vAttachWait.
3236e8d8bef9SDimitry Andric   std::string process_name;
3237e8d8bef9SDimitry Andric   if (!packet.GetHexByteString(process_name))
3238e8d8bef9SDimitry Andric     return SendIllFormedResponse(packet,
3239e8d8bef9SDimitry Andric                                  "vAttachOrWait failed to parse process name");
3240e8d8bef9SDimitry Andric 
3241e8d8bef9SDimitry Andric   LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name);
3242e8d8bef9SDimitry Andric 
3243e8d8bef9SDimitry Andric   Status error = AttachWaitProcess(process_name, true);
3244e8d8bef9SDimitry Andric   if (error.Fail()) {
3245e8d8bef9SDimitry Andric     LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name,
3246e8d8bef9SDimitry Andric              error);
3247e8d8bef9SDimitry Andric     return SendErrorResponse(error);
3248e8d8bef9SDimitry Andric   }
3249e8d8bef9SDimitry Andric 
3250e8d8bef9SDimitry Andric   // Notify we attached by sending a stop packet.
3251fe6060f1SDimitry Andric   return SendStopReasonForState(m_current_process->GetState());
3252e8d8bef9SDimitry Andric }
3253e8d8bef9SDimitry Andric 
3254e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult
32550b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
32560b57cec5SDimitry Andric   StopSTDIOForwarding();
32570b57cec5SDimitry Andric 
32580b57cec5SDimitry Andric   lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
32590b57cec5SDimitry Andric 
32600b57cec5SDimitry Andric   // Consume the ';' after D.
32610b57cec5SDimitry Andric   packet.SetFilePos(1);
32620b57cec5SDimitry Andric   if (packet.GetBytesLeft()) {
32630b57cec5SDimitry Andric     if (packet.GetChar() != ';')
32640b57cec5SDimitry Andric       return SendIllFormedResponse(packet, "D missing expected ';'");
32650b57cec5SDimitry Andric 
32660b57cec5SDimitry Andric     // Grab the PID from which we will detach (assume hex encoding).
32670b57cec5SDimitry Andric     pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16);
32680b57cec5SDimitry Andric     if (pid == LLDB_INVALID_PROCESS_ID)
32690b57cec5SDimitry Andric       return SendIllFormedResponse(packet, "D failed to parse the process id");
32700b57cec5SDimitry Andric   }
32710b57cec5SDimitry Andric 
3272fe6060f1SDimitry Andric   // Detach forked children if their PID was specified *or* no PID was requested
3273fe6060f1SDimitry Andric   // (i.e. detach-all packet).
3274fe6060f1SDimitry Andric   llvm::Error detach_error = llvm::Error::success();
3275fe6060f1SDimitry Andric   bool detached = false;
3276fe6060f1SDimitry Andric   for (auto it = m_debugged_processes.begin();
3277fe6060f1SDimitry Andric        it != m_debugged_processes.end();) {
3278fe6060f1SDimitry Andric     if (pid == LLDB_INVALID_PROCESS_ID || pid == it->first) {
3279fe6060f1SDimitry Andric       if (llvm::Error e = it->second->Detach().ToError())
3280fe6060f1SDimitry Andric         detach_error = llvm::joinErrors(std::move(detach_error), std::move(e));
3281fe6060f1SDimitry Andric       else {
3282fe6060f1SDimitry Andric         if (it->second.get() == m_current_process)
3283fe6060f1SDimitry Andric           m_current_process = nullptr;
3284fe6060f1SDimitry Andric         if (it->second.get() == m_continue_process)
3285fe6060f1SDimitry Andric           m_continue_process = nullptr;
3286fe6060f1SDimitry Andric         it = m_debugged_processes.erase(it);
3287fe6060f1SDimitry Andric         detached = true;
3288fe6060f1SDimitry Andric         continue;
3289fe6060f1SDimitry Andric       }
3290fe6060f1SDimitry Andric     }
3291fe6060f1SDimitry Andric     ++it;
32920b57cec5SDimitry Andric   }
32930b57cec5SDimitry Andric 
3294fe6060f1SDimitry Andric   if (detach_error)
3295fe6060f1SDimitry Andric     return SendErrorResponse(std::move(detach_error));
3296fe6060f1SDimitry Andric   if (!detached)
3297fe6060f1SDimitry Andric     return SendErrorResponse(Status("PID %" PRIu64 " not traced", pid));
32980b57cec5SDimitry Andric   return SendOKResponse();
32990b57cec5SDimitry Andric }
33000b57cec5SDimitry Andric 
33010b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
33020b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
33030b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
33040b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
33050b57cec5SDimitry Andric 
33060b57cec5SDimitry Andric   packet.SetFilePos(strlen("qThreadStopInfo"));
3307fe6060f1SDimitry Andric   const lldb::tid_t tid = packet.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
33080b57cec5SDimitry Andric   if (tid == LLDB_INVALID_THREAD_ID) {
33099dba64beSDimitry Andric     LLDB_LOGF(log,
33109dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s failed, could not "
33110b57cec5SDimitry Andric               "parse thread id from request \"%s\"",
33129dba64beSDimitry Andric               __FUNCTION__, packet.GetStringRef().data());
33130b57cec5SDimitry Andric     return SendErrorResponse(0x15);
33140b57cec5SDimitry Andric   }
33150b57cec5SDimitry Andric   return SendStopReplyPacketForThread(tid);
33160b57cec5SDimitry Andric }
33170b57cec5SDimitry Andric 
33180b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
33190b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo(
33200b57cec5SDimitry Andric     StringExtractorGDBRemote &) {
33210b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
33220b57cec5SDimitry Andric 
33230b57cec5SDimitry Andric   // Ensure we have a debugged process.
3324fe6060f1SDimitry Andric   if (!m_current_process ||
3325fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
33260b57cec5SDimitry Andric     return SendErrorResponse(50);
3327fe6060f1SDimitry Andric   LLDB_LOG(log, "preparing packet for pid {0}", m_current_process->GetID());
33280b57cec5SDimitry Andric 
33290b57cec5SDimitry Andric   StreamString response;
33300b57cec5SDimitry Andric   const bool threads_with_valid_stop_info_only = false;
3331fe6060f1SDimitry Andric   llvm::Expected<json::Value> threads_info =
3332fe6060f1SDimitry Andric       GetJSONThreadsInfo(*m_current_process, threads_with_valid_stop_info_only);
33339dba64beSDimitry Andric   if (!threads_info) {
3334480093f4SDimitry Andric     LLDB_LOG_ERROR(log, threads_info.takeError(),
3335480093f4SDimitry Andric                    "failed to prepare a packet for pid {1}: {0}",
3336fe6060f1SDimitry Andric                    m_current_process->GetID());
33370b57cec5SDimitry Andric     return SendErrorResponse(52);
33380b57cec5SDimitry Andric   }
33390b57cec5SDimitry Andric 
33409dba64beSDimitry Andric   response.AsRawOstream() << *threads_info;
33410b57cec5SDimitry Andric   StreamGDBRemote escaped_response;
33420b57cec5SDimitry Andric   escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
33430b57cec5SDimitry Andric   return SendPacketNoLock(escaped_response.GetString());
33440b57cec5SDimitry Andric }
33450b57cec5SDimitry Andric 
33460b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
33470b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo(
33480b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
33490b57cec5SDimitry Andric   // Fail if we don't have a current process.
3350fe6060f1SDimitry Andric   if (!m_current_process ||
3351fe6060f1SDimitry Andric       m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)
33520b57cec5SDimitry Andric     return SendErrorResponse(68);
33530b57cec5SDimitry Andric 
33540b57cec5SDimitry Andric   packet.SetFilePos(strlen("qWatchpointSupportInfo"));
33550b57cec5SDimitry Andric   if (packet.GetBytesLeft() == 0)
33560b57cec5SDimitry Andric     return SendOKResponse();
33570b57cec5SDimitry Andric   if (packet.GetChar() != ':')
33580b57cec5SDimitry Andric     return SendErrorResponse(67);
33590b57cec5SDimitry Andric 
3360fe6060f1SDimitry Andric   auto hw_debug_cap = m_current_process->GetHardwareDebugSupportInfo();
33610b57cec5SDimitry Andric 
33620b57cec5SDimitry Andric   StreamGDBRemote response;
33630b57cec5SDimitry Andric   if (hw_debug_cap == llvm::None)
33640b57cec5SDimitry Andric     response.Printf("num:0;");
33650b57cec5SDimitry Andric   else
33660b57cec5SDimitry Andric     response.Printf("num:%d;", hw_debug_cap->second);
33670b57cec5SDimitry Andric 
33680b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
33690b57cec5SDimitry Andric }
33700b57cec5SDimitry Andric 
33710b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
33720b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress(
33730b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
33740b57cec5SDimitry Andric   // Fail if we don't have a current process.
3375fe6060f1SDimitry Andric   if (!m_current_process ||
3376fe6060f1SDimitry Andric       m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)
33770b57cec5SDimitry Andric     return SendErrorResponse(67);
33780b57cec5SDimitry Andric 
33790b57cec5SDimitry Andric   packet.SetFilePos(strlen("qFileLoadAddress:"));
33800b57cec5SDimitry Andric   if (packet.GetBytesLeft() == 0)
33810b57cec5SDimitry Andric     return SendErrorResponse(68);
33820b57cec5SDimitry Andric 
33830b57cec5SDimitry Andric   std::string file_name;
33840b57cec5SDimitry Andric   packet.GetHexByteString(file_name);
33850b57cec5SDimitry Andric 
33860b57cec5SDimitry Andric   lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
33870b57cec5SDimitry Andric   Status error =
3388fe6060f1SDimitry Andric       m_current_process->GetFileLoadAddress(file_name, file_load_address);
33890b57cec5SDimitry Andric   if (error.Fail())
33900b57cec5SDimitry Andric     return SendErrorResponse(69);
33910b57cec5SDimitry Andric 
33920b57cec5SDimitry Andric   if (file_load_address == LLDB_INVALID_ADDRESS)
33930b57cec5SDimitry Andric     return SendErrorResponse(1); // File not loaded
33940b57cec5SDimitry Andric 
33950b57cec5SDimitry Andric   StreamGDBRemote response;
33960b57cec5SDimitry Andric   response.PutHex64(file_load_address);
33970b57cec5SDimitry Andric   return SendPacketNoLock(response.GetString());
33980b57cec5SDimitry Andric }
33990b57cec5SDimitry Andric 
34000b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult
34010b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QPassSignals(
34020b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
34030b57cec5SDimitry Andric   std::vector<int> signals;
34040b57cec5SDimitry Andric   packet.SetFilePos(strlen("QPassSignals:"));
34050b57cec5SDimitry Andric 
34060b57cec5SDimitry Andric   // Read sequence of hex signal numbers divided by a semicolon and optionally
34070b57cec5SDimitry Andric   // spaces.
34080b57cec5SDimitry Andric   while (packet.GetBytesLeft() > 0) {
34090b57cec5SDimitry Andric     int signal = packet.GetS32(-1, 16);
34100b57cec5SDimitry Andric     if (signal < 0)
34110b57cec5SDimitry Andric       return SendIllFormedResponse(packet, "Failed to parse signal number.");
34120b57cec5SDimitry Andric     signals.push_back(signal);
34130b57cec5SDimitry Andric 
34140b57cec5SDimitry Andric     packet.SkipSpaces();
34150b57cec5SDimitry Andric     char separator = packet.GetChar();
34160b57cec5SDimitry Andric     if (separator == '\0')
34170b57cec5SDimitry Andric       break; // End of string
34180b57cec5SDimitry Andric     if (separator != ';')
34190b57cec5SDimitry Andric       return SendIllFormedResponse(packet, "Invalid separator,"
34200b57cec5SDimitry Andric                                             " expected semicolon.");
34210b57cec5SDimitry Andric   }
34220b57cec5SDimitry Andric 
34230b57cec5SDimitry Andric   // Fail if we don't have a current process.
3424fe6060f1SDimitry Andric   if (!m_current_process)
34250b57cec5SDimitry Andric     return SendErrorResponse(68);
34260b57cec5SDimitry Andric 
3427fe6060f1SDimitry Andric   Status error = m_current_process->IgnoreSignals(signals);
34280b57cec5SDimitry Andric   if (error.Fail())
34290b57cec5SDimitry Andric     return SendErrorResponse(69);
34300b57cec5SDimitry Andric 
34310b57cec5SDimitry Andric   return SendOKResponse();
34320b57cec5SDimitry Andric }
34330b57cec5SDimitry Andric 
3434fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult
3435fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qMemTags(
3436fe6060f1SDimitry Andric     StringExtractorGDBRemote &packet) {
3437fe6060f1SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
3438fe6060f1SDimitry Andric 
3439fe6060f1SDimitry Andric   // Ensure we have a process.
3440fe6060f1SDimitry Andric   if (!m_current_process ||
3441fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
3442fe6060f1SDimitry Andric     LLDB_LOGF(
3443fe6060f1SDimitry Andric         log,
3444fe6060f1SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
3445fe6060f1SDimitry Andric         __FUNCTION__);
3446fe6060f1SDimitry Andric     return SendErrorResponse(1);
3447fe6060f1SDimitry Andric   }
3448fe6060f1SDimitry Andric 
3449fe6060f1SDimitry Andric   // We are expecting
3450fe6060f1SDimitry Andric   // qMemTags:<hex address>,<hex length>:<hex type>
3451fe6060f1SDimitry Andric 
3452fe6060f1SDimitry Andric   // Address
3453fe6060f1SDimitry Andric   packet.SetFilePos(strlen("qMemTags:"));
3454fe6060f1SDimitry Andric   const char *current_char = packet.Peek();
3455fe6060f1SDimitry Andric   if (!current_char || *current_char == ',')
3456fe6060f1SDimitry Andric     return SendIllFormedResponse(packet, "Missing address in qMemTags packet");
3457fe6060f1SDimitry Andric   const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0);
3458fe6060f1SDimitry Andric 
3459fe6060f1SDimitry Andric   // Length
3460fe6060f1SDimitry Andric   char previous_char = packet.GetChar();
3461fe6060f1SDimitry Andric   current_char = packet.Peek();
3462fe6060f1SDimitry Andric   // If we don't have a separator or the length field is empty
3463fe6060f1SDimitry Andric   if (previous_char != ',' || (current_char && *current_char == ':'))
3464fe6060f1SDimitry Andric     return SendIllFormedResponse(packet,
3465fe6060f1SDimitry Andric                                  "Invalid addr,length pair in qMemTags packet");
3466fe6060f1SDimitry Andric 
3467fe6060f1SDimitry Andric   if (packet.GetBytesLeft() < 1)
3468fe6060f1SDimitry Andric     return SendIllFormedResponse(
3469fe6060f1SDimitry Andric         packet, "Too short qMemtags: packet (looking for length)");
3470fe6060f1SDimitry Andric   const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0);
3471fe6060f1SDimitry Andric 
3472fe6060f1SDimitry Andric   // Type
3473fe6060f1SDimitry Andric   const char *invalid_type_err = "Invalid type field in qMemTags: packet";
3474fe6060f1SDimitry Andric   if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':')
3475fe6060f1SDimitry Andric     return SendIllFormedResponse(packet, invalid_type_err);
3476fe6060f1SDimitry Andric 
34776e75b2fbSDimitry Andric   // Type is a signed integer but packed into the packet as its raw bytes.
34786e75b2fbSDimitry Andric   // However, our GetU64 uses strtoull which allows +/-. We do not want this.
34796e75b2fbSDimitry Andric   const char *first_type_char = packet.Peek();
34806e75b2fbSDimitry Andric   if (first_type_char && (*first_type_char == '+' || *first_type_char == '-'))
34816e75b2fbSDimitry Andric     return SendIllFormedResponse(packet, invalid_type_err);
34826e75b2fbSDimitry Andric 
34836e75b2fbSDimitry Andric   // Extract type as unsigned then cast to signed.
34846e75b2fbSDimitry Andric   // Using a uint64_t here so that we have some value outside of the 32 bit
34856e75b2fbSDimitry Andric   // range to use as the invalid return value.
34866e75b2fbSDimitry Andric   uint64_t raw_type =
34876e75b2fbSDimitry Andric       packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16);
34886e75b2fbSDimitry Andric 
34896e75b2fbSDimitry Andric   if ( // Make sure the cast below would be valid
34906e75b2fbSDimitry Andric       raw_type > std::numeric_limits<uint32_t>::max() ||
3491fe6060f1SDimitry Andric       // To catch inputs like "123aardvark" that will parse but clearly aren't
3492fe6060f1SDimitry Andric       // valid in this case.
3493fe6060f1SDimitry Andric       packet.GetBytesLeft()) {
3494fe6060f1SDimitry Andric     return SendIllFormedResponse(packet, invalid_type_err);
3495fe6060f1SDimitry Andric   }
3496fe6060f1SDimitry Andric 
34976e75b2fbSDimitry Andric   // First narrow to 32 bits otherwise the copy into type would take
34986e75b2fbSDimitry Andric   // the wrong 4 bytes on big endian.
34996e75b2fbSDimitry Andric   uint32_t raw_type_32 = raw_type;
35006e75b2fbSDimitry Andric   int32_t type = reinterpret_cast<int32_t &>(raw_type_32);
35016e75b2fbSDimitry Andric 
3502fe6060f1SDimitry Andric   StreamGDBRemote response;
3503fe6060f1SDimitry Andric   std::vector<uint8_t> tags;
3504fe6060f1SDimitry Andric   Status error = m_current_process->ReadMemoryTags(type, addr, length, tags);
3505fe6060f1SDimitry Andric   if (error.Fail())
3506fe6060f1SDimitry Andric     return SendErrorResponse(1);
3507fe6060f1SDimitry Andric 
3508fe6060f1SDimitry Andric   // This m is here in case we want to support multi part replies in the future.
3509fe6060f1SDimitry Andric   // In the same manner as qfThreadInfo/qsThreadInfo.
3510fe6060f1SDimitry Andric   response.PutChar('m');
3511fe6060f1SDimitry Andric   response.PutBytesAsRawHex8(tags.data(), tags.size());
3512fe6060f1SDimitry Andric   return SendPacketNoLock(response.GetString());
3513fe6060f1SDimitry Andric }
3514fe6060f1SDimitry Andric 
3515fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult
3516fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QMemTags(
3517fe6060f1SDimitry Andric     StringExtractorGDBRemote &packet) {
3518fe6060f1SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
3519fe6060f1SDimitry Andric 
3520fe6060f1SDimitry Andric   // Ensure we have a process.
3521fe6060f1SDimitry Andric   if (!m_current_process ||
3522fe6060f1SDimitry Andric       (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
3523fe6060f1SDimitry Andric     LLDB_LOGF(
3524fe6060f1SDimitry Andric         log,
3525fe6060f1SDimitry Andric         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
3526fe6060f1SDimitry Andric         __FUNCTION__);
3527fe6060f1SDimitry Andric     return SendErrorResponse(1);
3528fe6060f1SDimitry Andric   }
3529fe6060f1SDimitry Andric 
3530fe6060f1SDimitry Andric   // We are expecting
3531fe6060f1SDimitry Andric   // QMemTags:<hex address>,<hex length>:<hex type>:<tags as hex bytes>
3532fe6060f1SDimitry Andric 
3533fe6060f1SDimitry Andric   // Address
3534fe6060f1SDimitry Andric   packet.SetFilePos(strlen("QMemTags:"));
3535fe6060f1SDimitry Andric   const char *current_char = packet.Peek();
3536fe6060f1SDimitry Andric   if (!current_char || *current_char == ',')
3537fe6060f1SDimitry Andric     return SendIllFormedResponse(packet, "Missing address in QMemTags packet");
3538fe6060f1SDimitry Andric   const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0);
3539fe6060f1SDimitry Andric 
3540fe6060f1SDimitry Andric   // Length
3541fe6060f1SDimitry Andric   char previous_char = packet.GetChar();
3542fe6060f1SDimitry Andric   current_char = packet.Peek();
3543fe6060f1SDimitry Andric   // If we don't have a separator or the length field is empty
3544fe6060f1SDimitry Andric   if (previous_char != ',' || (current_char && *current_char == ':'))
3545fe6060f1SDimitry Andric     return SendIllFormedResponse(packet,
3546fe6060f1SDimitry Andric                                  "Invalid addr,length pair in QMemTags packet");
3547fe6060f1SDimitry Andric 
3548fe6060f1SDimitry Andric   if (packet.GetBytesLeft() < 1)
3549fe6060f1SDimitry Andric     return SendIllFormedResponse(
3550fe6060f1SDimitry Andric         packet, "Too short QMemtags: packet (looking for length)");
3551fe6060f1SDimitry Andric   const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0);
3552fe6060f1SDimitry Andric 
3553fe6060f1SDimitry Andric   // Type
3554fe6060f1SDimitry Andric   const char *invalid_type_err = "Invalid type field in QMemTags: packet";
3555fe6060f1SDimitry Andric   if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':')
3556fe6060f1SDimitry Andric     return SendIllFormedResponse(packet, invalid_type_err);
3557fe6060f1SDimitry Andric 
3558fe6060f1SDimitry Andric   // Our GetU64 uses strtoull which allows leading +/-, we don't want that.
3559fe6060f1SDimitry Andric   const char *first_type_char = packet.Peek();
3560fe6060f1SDimitry Andric   if (first_type_char && (*first_type_char == '+' || *first_type_char == '-'))
3561fe6060f1SDimitry Andric     return SendIllFormedResponse(packet, invalid_type_err);
3562fe6060f1SDimitry Andric 
3563fe6060f1SDimitry Andric   // The type is a signed integer but is in the packet as its raw bytes.
3564fe6060f1SDimitry Andric   // So parse first as unsigned then cast to signed later.
3565fe6060f1SDimitry Andric   // We extract to 64 bit, even though we only expect 32, so that we've
3566fe6060f1SDimitry Andric   // got some invalid value we can check for.
3567fe6060f1SDimitry Andric   uint64_t raw_type =
3568fe6060f1SDimitry Andric       packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16);
3569fe6060f1SDimitry Andric   if (raw_type > std::numeric_limits<uint32_t>::max())
3570fe6060f1SDimitry Andric     return SendIllFormedResponse(packet, invalid_type_err);
35716e75b2fbSDimitry Andric 
35726e75b2fbSDimitry Andric   // First narrow to 32 bits. Otherwise the copy below would get the wrong
35736e75b2fbSDimitry Andric   // 4 bytes on big endian.
35746e75b2fbSDimitry Andric   uint32_t raw_type_32 = raw_type;
35756e75b2fbSDimitry Andric   int32_t type = reinterpret_cast<int32_t &>(raw_type_32);
3576fe6060f1SDimitry Andric 
3577fe6060f1SDimitry Andric   // Tag data
3578fe6060f1SDimitry Andric   if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':')
3579fe6060f1SDimitry Andric     return SendIllFormedResponse(packet,
3580fe6060f1SDimitry Andric                                  "Missing tag data in QMemTags: packet");
3581fe6060f1SDimitry Andric 
3582fe6060f1SDimitry Andric   // Must be 2 chars per byte
3583fe6060f1SDimitry Andric   const char *invalid_data_err = "Invalid tag data in QMemTags: packet";
3584fe6060f1SDimitry Andric   if (packet.GetBytesLeft() % 2)
3585fe6060f1SDimitry Andric     return SendIllFormedResponse(packet, invalid_data_err);
3586fe6060f1SDimitry Andric 
3587fe6060f1SDimitry Andric   // This is bytes here and is unpacked into target specific tags later
3588fe6060f1SDimitry Andric   // We cannot assume that number of bytes == length here because the server
3589fe6060f1SDimitry Andric   // can repeat tags to fill a given range.
3590fe6060f1SDimitry Andric   std::vector<uint8_t> tag_data;
3591fe6060f1SDimitry Andric   // Zero length writes will not have any tag data
3592fe6060f1SDimitry Andric   // (but we pass them on because it will still check that tagging is enabled)
3593fe6060f1SDimitry Andric   if (packet.GetBytesLeft()) {
3594fe6060f1SDimitry Andric     size_t byte_count = packet.GetBytesLeft() / 2;
3595fe6060f1SDimitry Andric     tag_data.resize(byte_count);
3596fe6060f1SDimitry Andric     size_t converted_bytes = packet.GetHexBytes(tag_data, 0);
3597fe6060f1SDimitry Andric     if (converted_bytes != byte_count) {
3598fe6060f1SDimitry Andric       return SendIllFormedResponse(packet, invalid_data_err);
3599fe6060f1SDimitry Andric     }
3600fe6060f1SDimitry Andric   }
3601fe6060f1SDimitry Andric 
3602fe6060f1SDimitry Andric   Status status =
3603fe6060f1SDimitry Andric       m_current_process->WriteMemoryTags(type, addr, length, tag_data);
3604fe6060f1SDimitry Andric   return status.Success() ? SendOKResponse() : SendErrorResponse(1);
3605fe6060f1SDimitry Andric }
3606fe6060f1SDimitry Andric 
36070b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
36080b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
36090b57cec5SDimitry Andric 
36100b57cec5SDimitry Andric   // Tell the stdio connection to shut down.
36110b57cec5SDimitry Andric   if (m_stdio_communication.IsConnected()) {
36120b57cec5SDimitry Andric     auto connection = m_stdio_communication.GetConnection();
36130b57cec5SDimitry Andric     if (connection) {
36140b57cec5SDimitry Andric       Status error;
36150b57cec5SDimitry Andric       connection->Disconnect(&error);
36160b57cec5SDimitry Andric 
36170b57cec5SDimitry Andric       if (error.Success()) {
36189dba64beSDimitry Andric         LLDB_LOGF(log,
36199dba64beSDimitry Andric                   "GDBRemoteCommunicationServerLLGS::%s disconnect process "
36200b57cec5SDimitry Andric                   "terminal stdio - SUCCESS",
36210b57cec5SDimitry Andric                   __FUNCTION__);
36220b57cec5SDimitry Andric       } else {
36239dba64beSDimitry Andric         LLDB_LOGF(log,
36249dba64beSDimitry Andric                   "GDBRemoteCommunicationServerLLGS::%s disconnect process "
36250b57cec5SDimitry Andric                   "terminal stdio - FAIL: %s",
36260b57cec5SDimitry Andric                   __FUNCTION__, error.AsCString());
36270b57cec5SDimitry Andric       }
36280b57cec5SDimitry Andric     }
36290b57cec5SDimitry Andric   }
36300b57cec5SDimitry Andric }
36310b57cec5SDimitry Andric 
36320b57cec5SDimitry Andric NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
36330b57cec5SDimitry Andric     StringExtractorGDBRemote &packet) {
36340b57cec5SDimitry Andric   // We have no thread if we don't have a process.
3635fe6060f1SDimitry Andric   if (!m_current_process ||
3636fe6060f1SDimitry Andric       m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)
36370b57cec5SDimitry Andric     return nullptr;
36380b57cec5SDimitry Andric 
36390b57cec5SDimitry Andric   // If the client hasn't asked for thread suffix support, there will not be a
36400b57cec5SDimitry Andric   // thread suffix. Use the current thread in that case.
36410b57cec5SDimitry Andric   if (!m_thread_suffix_supported) {
36420b57cec5SDimitry Andric     const lldb::tid_t current_tid = GetCurrentThreadID();
36430b57cec5SDimitry Andric     if (current_tid == LLDB_INVALID_THREAD_ID)
36440b57cec5SDimitry Andric       return nullptr;
36450b57cec5SDimitry Andric     else if (current_tid == 0) {
36460b57cec5SDimitry Andric       // Pick a thread.
3647fe6060f1SDimitry Andric       return m_current_process->GetThreadAtIndex(0);
36480b57cec5SDimitry Andric     } else
3649fe6060f1SDimitry Andric       return m_current_process->GetThreadByID(current_tid);
36500b57cec5SDimitry Andric   }
36510b57cec5SDimitry Andric 
36520b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
36530b57cec5SDimitry Andric 
36540b57cec5SDimitry Andric   // Parse out the ';'.
36550b57cec5SDimitry Andric   if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') {
36569dba64beSDimitry Andric     LLDB_LOGF(log,
36579dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
36580b57cec5SDimitry Andric               "error: expected ';' prior to start of thread suffix: packet "
36590b57cec5SDimitry Andric               "contents = '%s'",
36609dba64beSDimitry Andric               __FUNCTION__, packet.GetStringRef().data());
36610b57cec5SDimitry Andric     return nullptr;
36620b57cec5SDimitry Andric   }
36630b57cec5SDimitry Andric 
36640b57cec5SDimitry Andric   if (!packet.GetBytesLeft())
36650b57cec5SDimitry Andric     return nullptr;
36660b57cec5SDimitry Andric 
36670b57cec5SDimitry Andric   // Parse out thread: portion.
36680b57cec5SDimitry Andric   if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) {
36699dba64beSDimitry Andric     LLDB_LOGF(log,
36709dba64beSDimitry Andric               "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
36710b57cec5SDimitry Andric               "error: expected 'thread:' but not found, packet contents = "
36720b57cec5SDimitry Andric               "'%s'",
36739dba64beSDimitry Andric               __FUNCTION__, packet.GetStringRef().data());
36740b57cec5SDimitry Andric     return nullptr;
36750b57cec5SDimitry Andric   }
36760b57cec5SDimitry Andric   packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
36770b57cec5SDimitry Andric   const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
36780b57cec5SDimitry Andric   if (tid != 0)
3679fe6060f1SDimitry Andric     return m_current_process->GetThreadByID(tid);
36800b57cec5SDimitry Andric 
36810b57cec5SDimitry Andric   return nullptr;
36820b57cec5SDimitry Andric }
36830b57cec5SDimitry Andric 
36840b57cec5SDimitry Andric lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const {
36850b57cec5SDimitry Andric   if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) {
36860b57cec5SDimitry Andric     // Use whatever the debug process says is the current thread id since the
36870b57cec5SDimitry Andric     // protocol either didn't specify or specified we want any/all threads
36880b57cec5SDimitry Andric     // marked as the current thread.
3689fe6060f1SDimitry Andric     if (!m_current_process)
36900b57cec5SDimitry Andric       return LLDB_INVALID_THREAD_ID;
3691fe6060f1SDimitry Andric     return m_current_process->GetCurrentThreadID();
36920b57cec5SDimitry Andric   }
36930b57cec5SDimitry Andric   // Use the specific current thread id set by the gdb remote protocol.
36940b57cec5SDimitry Andric   return m_current_tid;
36950b57cec5SDimitry Andric }
36960b57cec5SDimitry Andric 
36970b57cec5SDimitry Andric uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() {
36980b57cec5SDimitry Andric   std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
36990b57cec5SDimitry Andric   return m_next_saved_registers_id++;
37000b57cec5SDimitry Andric }
37010b57cec5SDimitry Andric 
37020b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() {
37030b57cec5SDimitry Andric   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
37040b57cec5SDimitry Andric 
37050b57cec5SDimitry Andric   LLDB_LOG(log, "clearing {0} xfer buffers", m_xfer_buffer_map.size());
37060b57cec5SDimitry Andric   m_xfer_buffer_map.clear();
37070b57cec5SDimitry Andric }
37080b57cec5SDimitry Andric 
37090b57cec5SDimitry Andric FileSpec
37100b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
37110b57cec5SDimitry Andric                                                  const ArchSpec &arch) {
3712fe6060f1SDimitry Andric   if (m_current_process) {
37130b57cec5SDimitry Andric     FileSpec file_spec;
3714fe6060f1SDimitry Andric     if (m_current_process
37150b57cec5SDimitry Andric             ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec)
37160b57cec5SDimitry Andric             .Success()) {
37170b57cec5SDimitry Andric       if (FileSystem::Instance().Exists(file_spec))
37180b57cec5SDimitry Andric         return file_spec;
37190b57cec5SDimitry Andric     }
37200b57cec5SDimitry Andric   }
37210b57cec5SDimitry Andric 
37220b57cec5SDimitry Andric   return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
37230b57cec5SDimitry Andric }
37249dba64beSDimitry Andric 
37259dba64beSDimitry Andric std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue(
37269dba64beSDimitry Andric     llvm::StringRef value) {
37279dba64beSDimitry Andric   std::string result;
37289dba64beSDimitry Andric   for (const char &c : value) {
37299dba64beSDimitry Andric     switch (c) {
37309dba64beSDimitry Andric     case '\'':
37319dba64beSDimitry Andric       result += "&apos;";
37329dba64beSDimitry Andric       break;
37339dba64beSDimitry Andric     case '"':
37349dba64beSDimitry Andric       result += "&quot;";
37359dba64beSDimitry Andric       break;
37369dba64beSDimitry Andric     case '<':
37379dba64beSDimitry Andric       result += "&lt;";
37389dba64beSDimitry Andric       break;
37399dba64beSDimitry Andric     case '>':
37409dba64beSDimitry Andric       result += "&gt;";
37419dba64beSDimitry Andric       break;
37429dba64beSDimitry Andric     default:
37439dba64beSDimitry Andric       result += c;
37449dba64beSDimitry Andric       break;
37459dba64beSDimitry Andric     }
37469dba64beSDimitry Andric   }
37479dba64beSDimitry Andric   return result;
37489dba64beSDimitry Andric }
3749fe6060f1SDimitry Andric 
3750fe6060f1SDimitry Andric llvm::Expected<lldb::tid_t> GDBRemoteCommunicationServerLLGS::ReadTid(
3751fe6060f1SDimitry Andric     StringExtractorGDBRemote &packet, bool allow_all, lldb::pid_t default_pid) {
3752fe6060f1SDimitry Andric   assert(m_current_process);
3753fe6060f1SDimitry Andric   assert(m_current_process->GetID() != LLDB_INVALID_PROCESS_ID);
3754fe6060f1SDimitry Andric 
3755fe6060f1SDimitry Andric   auto pid_tid = packet.GetPidTid(default_pid);
3756fe6060f1SDimitry Andric   if (!pid_tid)
3757fe6060f1SDimitry Andric     return llvm::make_error<StringError>(inconvertibleErrorCode(),
3758fe6060f1SDimitry Andric                                          "Malformed thread-id");
3759fe6060f1SDimitry Andric 
3760fe6060f1SDimitry Andric   lldb::pid_t pid = pid_tid->first;
3761fe6060f1SDimitry Andric   lldb::tid_t tid = pid_tid->second;
3762fe6060f1SDimitry Andric 
3763fe6060f1SDimitry Andric   if (!allow_all && pid == StringExtractorGDBRemote::AllProcesses)
3764fe6060f1SDimitry Andric     return llvm::make_error<StringError>(
3765fe6060f1SDimitry Andric         inconvertibleErrorCode(),
3766fe6060f1SDimitry Andric         llvm::formatv("PID value {0} not allowed", pid == 0 ? 0 : -1));
3767fe6060f1SDimitry Andric 
3768fe6060f1SDimitry Andric   if (!allow_all && tid == StringExtractorGDBRemote::AllThreads)
3769fe6060f1SDimitry Andric     return llvm::make_error<StringError>(
3770fe6060f1SDimitry Andric         inconvertibleErrorCode(),
3771fe6060f1SDimitry Andric         llvm::formatv("TID value {0} not allowed", tid == 0 ? 0 : -1));
3772fe6060f1SDimitry Andric 
3773fe6060f1SDimitry Andric   if (pid != StringExtractorGDBRemote::AllProcesses) {
3774fe6060f1SDimitry Andric     if (pid != m_current_process->GetID())
3775fe6060f1SDimitry Andric       return llvm::make_error<StringError>(
3776fe6060f1SDimitry Andric           inconvertibleErrorCode(), llvm::formatv("PID {0} not debugged", pid));
3777fe6060f1SDimitry Andric   }
3778fe6060f1SDimitry Andric 
3779fe6060f1SDimitry Andric   return tid;
3780fe6060f1SDimitry Andric }
3781fe6060f1SDimitry Andric 
3782fe6060f1SDimitry Andric std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
3783fe6060f1SDimitry Andric     const llvm::ArrayRef<llvm::StringRef> client_features) {
3784fe6060f1SDimitry Andric   std::vector<std::string> ret =
3785fe6060f1SDimitry Andric       GDBRemoteCommunicationServerCommon::HandleFeatures(client_features);
3786fe6060f1SDimitry Andric   ret.insert(ret.end(), {
3787fe6060f1SDimitry Andric                             "QThreadSuffixSupported+",
3788fe6060f1SDimitry Andric                             "QListThreadsInStopReply+",
3789fe6060f1SDimitry Andric                             "qXfer:features:read+",
3790fe6060f1SDimitry Andric                         });
3791fe6060f1SDimitry Andric 
3792fe6060f1SDimitry Andric   // report server-only features
3793fe6060f1SDimitry Andric   using Extension = NativeProcessProtocol::Extension;
3794fe6060f1SDimitry Andric   Extension plugin_features = m_process_factory.GetSupportedExtensions();
3795fe6060f1SDimitry Andric   if (bool(plugin_features & Extension::pass_signals))
3796fe6060f1SDimitry Andric     ret.push_back("QPassSignals+");
3797fe6060f1SDimitry Andric   if (bool(plugin_features & Extension::auxv))
3798fe6060f1SDimitry Andric     ret.push_back("qXfer:auxv:read+");
3799fe6060f1SDimitry Andric   if (bool(plugin_features & Extension::libraries_svr4))
3800fe6060f1SDimitry Andric     ret.push_back("qXfer:libraries-svr4:read+");
3801fe6060f1SDimitry Andric   if (bool(plugin_features & Extension::memory_tagging))
3802fe6060f1SDimitry Andric     ret.push_back("memory-tagging+");
3803fe6060f1SDimitry Andric 
3804fe6060f1SDimitry Andric   // check for client features
3805fe6060f1SDimitry Andric   m_extensions_supported = {};
3806fe6060f1SDimitry Andric   for (llvm::StringRef x : client_features)
3807fe6060f1SDimitry Andric     m_extensions_supported |=
3808fe6060f1SDimitry Andric         llvm::StringSwitch<Extension>(x)
3809fe6060f1SDimitry Andric             .Case("multiprocess+", Extension::multiprocess)
3810fe6060f1SDimitry Andric             .Case("fork-events+", Extension::fork)
3811fe6060f1SDimitry Andric             .Case("vfork-events+", Extension::vfork)
3812fe6060f1SDimitry Andric             .Default({});
3813fe6060f1SDimitry Andric 
3814fe6060f1SDimitry Andric   m_extensions_supported &= plugin_features;
3815fe6060f1SDimitry Andric 
3816fe6060f1SDimitry Andric   // fork & vfork require multiprocess
3817fe6060f1SDimitry Andric   if (!bool(m_extensions_supported & Extension::multiprocess))
3818fe6060f1SDimitry Andric     m_extensions_supported &= ~(Extension::fork | Extension::vfork);
3819fe6060f1SDimitry Andric 
3820fe6060f1SDimitry Andric   // report only if actually supported
3821fe6060f1SDimitry Andric   if (bool(m_extensions_supported & Extension::multiprocess))
3822fe6060f1SDimitry Andric     ret.push_back("multiprocess+");
3823fe6060f1SDimitry Andric   if (bool(m_extensions_supported & Extension::fork))
3824fe6060f1SDimitry Andric     ret.push_back("fork-events+");
3825fe6060f1SDimitry Andric   if (bool(m_extensions_supported & Extension::vfork))
3826fe6060f1SDimitry Andric     ret.push_back("vfork-events+");
3827fe6060f1SDimitry Andric 
3828fe6060f1SDimitry Andric   for (auto &x : m_debugged_processes)
3829fe6060f1SDimitry Andric     SetEnabledExtensions(*x.second);
3830fe6060f1SDimitry Andric   return ret;
3831fe6060f1SDimitry Andric }
3832fe6060f1SDimitry Andric 
3833fe6060f1SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions(
3834fe6060f1SDimitry Andric     NativeProcessProtocol &process) {
3835fe6060f1SDimitry Andric   NativeProcessProtocol::Extension flags = m_extensions_supported;
3836fe6060f1SDimitry Andric   assert(!bool(flags & ~m_process_factory.GetSupportedExtensions()));
3837fe6060f1SDimitry Andric   process.SetEnabledExtensions(flags);
3838fe6060f1SDimitry Andric }
3839