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" 28349cc55cSDimitry Andric #include "lldb/Host/Socket.h" 290b57cec5SDimitry Andric #include "lldb/Host/common/NativeProcessProtocol.h" 300b57cec5SDimitry Andric #include "lldb/Host/common/NativeRegisterContext.h" 310b57cec5SDimitry Andric #include "lldb/Host/common/NativeThreadProtocol.h" 320b57cec5SDimitry Andric #include "lldb/Target/MemoryRegionInfo.h" 330b57cec5SDimitry Andric #include "lldb/Utility/Args.h" 340b57cec5SDimitry Andric #include "lldb/Utility/DataBuffer.h" 350b57cec5SDimitry Andric #include "lldb/Utility/Endian.h" 36e8d8bef9SDimitry Andric #include "lldb/Utility/GDBRemote.h" 370b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h" 3881ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 390b57cec5SDimitry Andric #include "lldb/Utility/Log.h" 400b57cec5SDimitry Andric #include "lldb/Utility/RegisterValue.h" 410b57cec5SDimitry Andric #include "lldb/Utility/State.h" 420b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 43e8d8bef9SDimitry Andric #include "lldb/Utility/UnimplementedError.h" 440b57cec5SDimitry Andric #include "lldb/Utility/UriParser.h" 450b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 469dba64beSDimitry Andric #include "llvm/Support/JSON.h" 470b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h" 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric #include "ProcessGDBRemote.h" 500b57cec5SDimitry Andric #include "ProcessGDBRemoteLog.h" 510b57cec5SDimitry Andric #include "lldb/Utility/StringExtractorGDBRemote.h" 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric using namespace lldb; 540b57cec5SDimitry Andric using namespace lldb_private; 550b57cec5SDimitry Andric using namespace lldb_private::process_gdb_remote; 560b57cec5SDimitry Andric using namespace llvm; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric // GDBRemote Errors 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric namespace { 610b57cec5SDimitry Andric enum GDBRemoteServerError { 620b57cec5SDimitry Andric // Set to the first unused error number in literal form below 630b57cec5SDimitry Andric eErrorFirst = 29, 640b57cec5SDimitry Andric eErrorNoProcess = eErrorFirst, 650b57cec5SDimitry Andric eErrorResume, 660b57cec5SDimitry Andric eErrorExitStatus 670b57cec5SDimitry Andric }; 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric // GDBRemoteCommunicationServerLLGS constructor 710b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( 720b57cec5SDimitry Andric MainLoop &mainloop, const NativeProcessProtocol::Factory &process_factory) 730b57cec5SDimitry Andric : GDBRemoteCommunicationServerCommon("gdb-remote.server", 740b57cec5SDimitry Andric "gdb-remote.server.rx_packet"), 750b57cec5SDimitry Andric m_mainloop(mainloop), m_process_factory(process_factory), 76fe6060f1SDimitry Andric m_current_process(nullptr), m_continue_process(nullptr), 770b57cec5SDimitry Andric m_stdio_communication("process.stdio") { 780b57cec5SDimitry Andric RegisterPacketHandlers(); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { 820b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C, 830b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_C); 840b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c, 850b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_c); 860b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D, 870b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_D); 880b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H, 890b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_H); 900b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I, 910b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_I); 920b57cec5SDimitry Andric RegisterMemberFunctionHandler( 930b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_interrupt, 940b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_interrupt); 950b57cec5SDimitry Andric RegisterMemberFunctionHandler( 960b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_m, 970b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_memory_read); 980b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M, 990b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_M); 100e8d8bef9SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType__M, 101e8d8bef9SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle__M); 102e8d8bef9SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType__m, 103e8d8bef9SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle__m); 1040b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p, 1050b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_p); 1060b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P, 1070b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_P); 1080b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC, 1090b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qC); 11081ad6265SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_T, 11181ad6265SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_T); 1120b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1130b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qfThreadInfo, 1140b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo); 1150b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1160b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress, 1170b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress); 1180b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1190b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir, 1200b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir); 1210b57cec5SDimitry Andric RegisterMemberFunctionHandler( 122fe6060f1SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported, 123fe6060f1SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported); 124fe6060f1SDimitry Andric RegisterMemberFunctionHandler( 125fe6060f1SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply, 126fe6060f1SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply); 127fe6060f1SDimitry Andric RegisterMemberFunctionHandler( 1280b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo, 1290b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo); 1300b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1310b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported, 1320b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported); 1330b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1340b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qProcessInfo, 1350b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo); 1360b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1370b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qRegisterInfo, 1380b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo); 1390b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1400b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState, 1410b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState); 1420b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1430b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState, 1440b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState); 1450b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1460b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR, 1470b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR); 1480b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1490b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, 1500b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir); 1510b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1520b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qsThreadInfo, 1530b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo); 1540b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1550b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo, 1560b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo); 1570b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1580b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_jThreadsInfo, 1590b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo); 1600b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1610b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo, 1620b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo); 1630b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1640b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qXfer, 1650b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qXfer); 1660b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s, 1670b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_s); 1680b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1690b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_stop_reason, 1700b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ? 1710b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1720b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vAttach, 1730b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vAttach); 1740b57cec5SDimitry Andric RegisterMemberFunctionHandler( 175e8d8bef9SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vAttachWait, 176e8d8bef9SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vAttachWait); 177e8d8bef9SDimitry Andric RegisterMemberFunctionHandler( 178e8d8bef9SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qVAttachOrWaitSupported, 179e8d8bef9SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported); 180e8d8bef9SDimitry Andric RegisterMemberFunctionHandler( 181e8d8bef9SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vAttachOrWait, 182e8d8bef9SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait); 183e8d8bef9SDimitry Andric RegisterMemberFunctionHandler( 1840b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vCont, 1850b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vCont); 1860b57cec5SDimitry Andric RegisterMemberFunctionHandler( 1870b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vCont_actions, 1880b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions); 1890b57cec5SDimitry Andric RegisterMemberFunctionHandler( 190349cc55cSDimitry Andric StringExtractorGDBRemote::eServerPacketType_vRun, 191349cc55cSDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vRun); 192349cc55cSDimitry Andric RegisterMemberFunctionHandler( 1930b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_x, 1940b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_memory_read); 1950b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z, 1960b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_Z); 1970b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z, 1980b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_z); 1990b57cec5SDimitry Andric RegisterMemberFunctionHandler( 2000b57cec5SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QPassSignals, 2010b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_QPassSignals); 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric RegisterMemberFunctionHandler( 204fe6060f1SDimitry Andric StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupported, 205fe6060f1SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported); 2060b57cec5SDimitry Andric RegisterMemberFunctionHandler( 207fe6060f1SDimitry Andric StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStart, 208fe6060f1SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart); 2090b57cec5SDimitry Andric RegisterMemberFunctionHandler( 210fe6060f1SDimitry Andric StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStop, 211fe6060f1SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop); 2120b57cec5SDimitry Andric RegisterMemberFunctionHandler( 213fe6060f1SDimitry Andric StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetState, 214fe6060f1SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState); 2150b57cec5SDimitry Andric RegisterMemberFunctionHandler( 216fe6060f1SDimitry Andric StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetBinaryData, 217fe6060f1SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g, 2200b57cec5SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_g); 2210b57cec5SDimitry Andric 222fe6060f1SDimitry Andric RegisterMemberFunctionHandler( 223fe6060f1SDimitry Andric StringExtractorGDBRemote::eServerPacketType_qMemTags, 224fe6060f1SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qMemTags); 225fe6060f1SDimitry Andric 226fe6060f1SDimitry Andric RegisterMemberFunctionHandler( 227fe6060f1SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QMemTags, 228fe6060f1SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_QMemTags); 229fe6060f1SDimitry Andric 2300b57cec5SDimitry Andric RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k, 2310b57cec5SDimitry Andric [this](StringExtractorGDBRemote packet, Status &error, 2320b57cec5SDimitry Andric bool &interrupt, bool &quit) { 2330b57cec5SDimitry Andric quit = true; 2340b57cec5SDimitry Andric return this->Handle_k(packet); 2350b57cec5SDimitry Andric }); 236349cc55cSDimitry Andric 237349cc55cSDimitry Andric RegisterMemberFunctionHandler( 23881ad6265SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vKill, 23981ad6265SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vKill); 24081ad6265SDimitry Andric 24181ad6265SDimitry Andric RegisterMemberFunctionHandler( 242349cc55cSDimitry Andric StringExtractorGDBRemote::eServerPacketType_qLLDBSaveCore, 243349cc55cSDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_qSaveCore); 24481ad6265SDimitry Andric 24581ad6265SDimitry Andric RegisterMemberFunctionHandler( 24681ad6265SDimitry Andric StringExtractorGDBRemote::eServerPacketType_QNonStop, 24781ad6265SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_QNonStop); 24881ad6265SDimitry Andric RegisterMemberFunctionHandler( 249fcaf7f86SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vStdio, 250fcaf7f86SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vStdio); 251fcaf7f86SDimitry Andric RegisterMemberFunctionHandler( 25281ad6265SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vStopped, 25381ad6265SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vStopped); 25481ad6265SDimitry Andric RegisterMemberFunctionHandler( 25581ad6265SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vCtrlC, 25681ad6265SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vCtrlC); 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) { 2600b57cec5SDimitry Andric m_process_launch_info = info; 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { 26481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric if (!m_process_launch_info.GetArguments().GetArgumentCount()) 2670b57cec5SDimitry Andric return Status("%s: no process command line specified to launch", 2680b57cec5SDimitry Andric __FUNCTION__); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric const bool should_forward_stdio = 2710b57cec5SDimitry Andric m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr || 2720b57cec5SDimitry Andric m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr || 2730b57cec5SDimitry Andric m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr; 2740b57cec5SDimitry Andric m_process_launch_info.SetLaunchInSeparateProcessGroup(true); 2750b57cec5SDimitry Andric m_process_launch_info.GetFlags().Set(eLaunchFlagDebug); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric if (should_forward_stdio) { 2789dba64beSDimitry Andric // Temporarily relax the following for Windows until we can take advantage 2799dba64beSDimitry Andric // of the recently added pty support. This doesn't really affect the use of 2809dba64beSDimitry Andric // lldb-server on Windows. 2819dba64beSDimitry Andric #if !defined(_WIN32) 2820b57cec5SDimitry Andric if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection()) 2830b57cec5SDimitry Andric return Status(std::move(Err)); 2849dba64beSDimitry Andric #endif 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric { 2880b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex); 289fe6060f1SDimitry Andric assert(m_debugged_processes.empty() && "lldb-server creating debugged " 2900b57cec5SDimitry Andric "process but one already exists"); 2910b57cec5SDimitry Andric auto process_or = 2920b57cec5SDimitry Andric m_process_factory.Launch(m_process_launch_info, *this, m_mainloop); 2930b57cec5SDimitry Andric if (!process_or) 2940b57cec5SDimitry Andric return Status(process_or.takeError()); 295fe6060f1SDimitry Andric m_continue_process = m_current_process = process_or->get(); 296fcaf7f86SDimitry Andric m_debugged_processes.emplace( 297fcaf7f86SDimitry Andric m_current_process->GetID(), 298fcaf7f86SDimitry Andric DebuggedProcess{std::move(*process_or), DebuggedProcess::Flag{}}); 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 301fe6060f1SDimitry Andric SetEnabledExtensions(*m_current_process); 302fe6060f1SDimitry Andric 3030b57cec5SDimitry Andric // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as 3040b57cec5SDimitry Andric // needed. llgs local-process debugging may specify PTY paths, which will 3050b57cec5SDimitry Andric // make these file actions non-null process launch -i/e/o will also make 3060b57cec5SDimitry Andric // these file actions non-null nullptr means that the traffic is expected to 3070b57cec5SDimitry Andric // flow over gdb-remote protocol 3080b57cec5SDimitry Andric if (should_forward_stdio) { 3090b57cec5SDimitry Andric // nullptr means it's not redirected to file or pty (in case of LLGS local) 3100b57cec5SDimitry Andric // at least one of stdio will be transferred pty<->gdb-remote we need to 311349cc55cSDimitry Andric // give the pty primary handle to this object to read and/or write 3120b57cec5SDimitry Andric LLDB_LOG(log, 3130b57cec5SDimitry Andric "pid = {0}: setting up stdout/stderr redirection via $O " 3140b57cec5SDimitry Andric "gdb-remote commands", 315fe6060f1SDimitry Andric m_current_process->GetID()); 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric // Setup stdout/stderr mapping from inferior to $O 318fe6060f1SDimitry Andric auto terminal_fd = m_current_process->GetTerminalFileDescriptor(); 3190b57cec5SDimitry Andric if (terminal_fd >= 0) { 3209dba64beSDimitry Andric LLDB_LOGF(log, 3219dba64beSDimitry Andric "ProcessGDBRemoteCommunicationServerLLGS::%s setting " 3220b57cec5SDimitry Andric "inferior STDIO fd to %d", 3230b57cec5SDimitry Andric __FUNCTION__, terminal_fd); 3240b57cec5SDimitry Andric Status status = SetSTDIOFileDescriptor(terminal_fd); 3250b57cec5SDimitry Andric if (status.Fail()) 3260b57cec5SDimitry Andric return status; 3270b57cec5SDimitry Andric } else { 3289dba64beSDimitry Andric LLDB_LOGF(log, 3299dba64beSDimitry Andric "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " 3300b57cec5SDimitry Andric "inferior STDIO since terminal fd reported as %d", 3310b57cec5SDimitry Andric __FUNCTION__, terminal_fd); 3320b57cec5SDimitry Andric } 3330b57cec5SDimitry Andric } else { 3340b57cec5SDimitry Andric LLDB_LOG(log, 3350b57cec5SDimitry Andric "pid = {0} skipping stdout/stderr redirection via $O: inferior " 3360b57cec5SDimitry Andric "will communicate over client-provided file descriptors", 337fe6060f1SDimitry Andric m_current_process->GetID()); 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric printf("Launched '%s' as process %" PRIu64 "...\n", 3410b57cec5SDimitry Andric m_process_launch_info.GetArguments().GetArgumentAtIndex(0), 342fe6060f1SDimitry Andric m_current_process->GetID()); 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric return Status(); 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { 34881ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3499dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, 3500b57cec5SDimitry Andric __FUNCTION__, pid); 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric // Before we try to attach, make sure we aren't already monitoring something 3530b57cec5SDimitry Andric // else. 354fe6060f1SDimitry Andric if (!m_debugged_processes.empty()) 3550b57cec5SDimitry Andric return Status("cannot attach to process %" PRIu64 3560b57cec5SDimitry Andric " when another process with pid %" PRIu64 3570b57cec5SDimitry Andric " is being debugged.", 358fe6060f1SDimitry Andric pid, m_current_process->GetID()); 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric // Try to attach. 3610b57cec5SDimitry Andric auto process_or = m_process_factory.Attach(pid, *this, m_mainloop); 3620b57cec5SDimitry Andric if (!process_or) { 3630b57cec5SDimitry Andric Status status(process_or.takeError()); 364349cc55cSDimitry Andric llvm::errs() << llvm::formatv("failed to attach to process {0}: {1}\n", pid, 3650b57cec5SDimitry Andric status); 3660b57cec5SDimitry Andric return status; 3670b57cec5SDimitry Andric } 368fe6060f1SDimitry Andric m_continue_process = m_current_process = process_or->get(); 369fcaf7f86SDimitry Andric m_debugged_processes.emplace( 370fcaf7f86SDimitry Andric m_current_process->GetID(), 371fcaf7f86SDimitry Andric DebuggedProcess{std::move(*process_or), DebuggedProcess::Flag{}}); 372fe6060f1SDimitry Andric SetEnabledExtensions(*m_current_process); 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric // Setup stdout/stderr mapping from inferior. 375fe6060f1SDimitry Andric auto terminal_fd = m_current_process->GetTerminalFileDescriptor(); 3760b57cec5SDimitry Andric if (terminal_fd >= 0) { 3779dba64beSDimitry Andric LLDB_LOGF(log, 3789dba64beSDimitry Andric "ProcessGDBRemoteCommunicationServerLLGS::%s setting " 3790b57cec5SDimitry Andric "inferior STDIO fd to %d", 3800b57cec5SDimitry Andric __FUNCTION__, terminal_fd); 3810b57cec5SDimitry Andric Status status = SetSTDIOFileDescriptor(terminal_fd); 3820b57cec5SDimitry Andric if (status.Fail()) 3830b57cec5SDimitry Andric return status; 3840b57cec5SDimitry Andric } else { 3859dba64beSDimitry Andric LLDB_LOGF(log, 3869dba64beSDimitry Andric "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " 3870b57cec5SDimitry Andric "inferior STDIO since terminal fd reported as %d", 3880b57cec5SDimitry Andric __FUNCTION__, terminal_fd); 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric printf("Attached to process %" PRIu64 "...\n", pid); 3920b57cec5SDimitry Andric return Status(); 3930b57cec5SDimitry Andric } 3940b57cec5SDimitry Andric 395e8d8bef9SDimitry Andric Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess( 396e8d8bef9SDimitry Andric llvm::StringRef process_name, bool include_existing) { 39781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 398e8d8bef9SDimitry Andric 399e8d8bef9SDimitry Andric std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1); 400e8d8bef9SDimitry Andric 401e8d8bef9SDimitry Andric // Create the matcher used to search the process list. 402e8d8bef9SDimitry Andric ProcessInstanceInfoList exclusion_list; 403e8d8bef9SDimitry Andric ProcessInstanceInfoMatch match_info; 404e8d8bef9SDimitry Andric match_info.GetProcessInfo().GetExecutableFile().SetFile( 405e8d8bef9SDimitry Andric process_name, llvm::sys::path::Style::native); 406e8d8bef9SDimitry Andric match_info.SetNameMatchType(NameMatch::Equals); 407e8d8bef9SDimitry Andric 408e8d8bef9SDimitry Andric if (include_existing) { 409e8d8bef9SDimitry Andric LLDB_LOG(log, "including existing processes in search"); 410e8d8bef9SDimitry Andric } else { 411e8d8bef9SDimitry Andric // Create the excluded process list before polling begins. 412e8d8bef9SDimitry Andric Host::FindProcesses(match_info, exclusion_list); 413e8d8bef9SDimitry Andric LLDB_LOG(log, "placed '{0}' processes in the exclusion list.", 414e8d8bef9SDimitry Andric exclusion_list.size()); 415e8d8bef9SDimitry Andric } 416e8d8bef9SDimitry Andric 417e8d8bef9SDimitry Andric LLDB_LOG(log, "waiting for '{0}' to appear", process_name); 418e8d8bef9SDimitry Andric 419e8d8bef9SDimitry Andric auto is_in_exclusion_list = 420e8d8bef9SDimitry Andric [&exclusion_list](const ProcessInstanceInfo &info) { 421e8d8bef9SDimitry Andric for (auto &excluded : exclusion_list) { 422e8d8bef9SDimitry Andric if (excluded.GetProcessID() == info.GetProcessID()) 423e8d8bef9SDimitry Andric return true; 424e8d8bef9SDimitry Andric } 425e8d8bef9SDimitry Andric return false; 426e8d8bef9SDimitry Andric }; 427e8d8bef9SDimitry Andric 428e8d8bef9SDimitry Andric ProcessInstanceInfoList loop_process_list; 429e8d8bef9SDimitry Andric while (true) { 430e8d8bef9SDimitry Andric loop_process_list.clear(); 431e8d8bef9SDimitry Andric if (Host::FindProcesses(match_info, loop_process_list)) { 432e8d8bef9SDimitry Andric // Remove all the elements that are in the exclusion list. 433e8d8bef9SDimitry Andric llvm::erase_if(loop_process_list, is_in_exclusion_list); 434e8d8bef9SDimitry Andric 435e8d8bef9SDimitry Andric // One match! We found the desired process. 436e8d8bef9SDimitry Andric if (loop_process_list.size() == 1) { 437e8d8bef9SDimitry Andric auto matching_process_pid = loop_process_list[0].GetProcessID(); 438e8d8bef9SDimitry Andric LLDB_LOG(log, "found pid {0}", matching_process_pid); 439e8d8bef9SDimitry Andric return AttachToProcess(matching_process_pid); 440e8d8bef9SDimitry Andric } 441e8d8bef9SDimitry Andric 442e8d8bef9SDimitry Andric // Multiple matches! Return an error reporting the PIDs we found. 443e8d8bef9SDimitry Andric if (loop_process_list.size() > 1) { 444e8d8bef9SDimitry Andric StreamString error_stream; 445e8d8bef9SDimitry Andric error_stream.Format( 446e8d8bef9SDimitry Andric "Multiple executables with name: '{0}' found. Pids: ", 447e8d8bef9SDimitry Andric process_name); 448e8d8bef9SDimitry Andric for (size_t i = 0; i < loop_process_list.size() - 1; ++i) { 449e8d8bef9SDimitry Andric error_stream.Format("{0}, ", loop_process_list[i].GetProcessID()); 450e8d8bef9SDimitry Andric } 451e8d8bef9SDimitry Andric error_stream.Format("{0}.", loop_process_list.back().GetProcessID()); 452e8d8bef9SDimitry Andric 453e8d8bef9SDimitry Andric Status error; 454e8d8bef9SDimitry Andric error.SetErrorString(error_stream.GetString()); 455e8d8bef9SDimitry Andric return error; 456e8d8bef9SDimitry Andric } 457e8d8bef9SDimitry Andric } 458e8d8bef9SDimitry Andric // No matches, we have not found the process. Sleep until next poll. 459e8d8bef9SDimitry Andric LLDB_LOG(log, "sleep {0} seconds", polling_interval); 460e8d8bef9SDimitry Andric std::this_thread::sleep_for(polling_interval); 461e8d8bef9SDimitry Andric } 462e8d8bef9SDimitry Andric } 463e8d8bef9SDimitry Andric 4640b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::InitializeDelegate( 4650b57cec5SDimitry Andric NativeProcessProtocol *process) { 4660b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 46781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 4680b57cec5SDimitry Andric if (log) { 4699dba64beSDimitry Andric LLDB_LOGF(log, 4709dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s called with " 4710b57cec5SDimitry Andric "NativeProcessProtocol pid %" PRIu64 ", current state: %s", 4720b57cec5SDimitry Andric __FUNCTION__, process->GetID(), 4730b57cec5SDimitry Andric StateAsCString(process->GetState())); 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4780b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendWResponse( 4790b57cec5SDimitry Andric NativeProcessProtocol *process) { 4800b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 48181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric // send W notification 4840b57cec5SDimitry Andric auto wait_status = process->GetExitStatus(); 4850b57cec5SDimitry Andric if (!wait_status) { 4860b57cec5SDimitry Andric LLDB_LOG(log, "pid = {0}, failed to retrieve process exit status", 4870b57cec5SDimitry Andric process->GetID()); 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric StreamGDBRemote response; 4900b57cec5SDimitry Andric response.PutChar('E'); 4910b57cec5SDimitry Andric response.PutHex8(GDBRemoteServerError::eErrorExitStatus); 4920b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric LLDB_LOG(log, "pid = {0}, returning exit type {1}", process->GetID(), 4960b57cec5SDimitry Andric *wait_status); 4970b57cec5SDimitry Andric 49881ad6265SDimitry Andric // If the process was killed through vKill, return "OK". 499fcaf7f86SDimitry Andric if (bool(m_debugged_processes.at(process->GetID()).flags & 500fcaf7f86SDimitry Andric DebuggedProcess::Flag::vkilled)) 50181ad6265SDimitry Andric return SendOKResponse(); 50281ad6265SDimitry Andric 5030b57cec5SDimitry Andric StreamGDBRemote response; 5040b57cec5SDimitry Andric response.Format("{0:g}", *wait_status); 505fcaf7f86SDimitry Andric if (bool(m_extensions_supported & 506fcaf7f86SDimitry Andric NativeProcessProtocol::Extension::multiprocess)) 50781ad6265SDimitry Andric response.Format(";process:{0:x-}", process->GetID()); 50881ad6265SDimitry Andric if (m_non_stop) 50981ad6265SDimitry Andric return SendNotificationPacketNoLock("Stop", m_stop_notification_queue, 51081ad6265SDimitry Andric response.GetString()); 5110b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric static void AppendHexValue(StreamString &response, const uint8_t *buf, 5150b57cec5SDimitry Andric uint32_t buf_size, bool swap) { 5160b57cec5SDimitry Andric int64_t i; 5170b57cec5SDimitry Andric if (swap) { 5180b57cec5SDimitry Andric for (i = buf_size - 1; i >= 0; i--) 5190b57cec5SDimitry Andric response.PutHex8(buf[i]); 5200b57cec5SDimitry Andric } else { 5210b57cec5SDimitry Andric for (i = 0; i < buf_size; i++) 5220b57cec5SDimitry Andric response.PutHex8(buf[i]); 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric } 5250b57cec5SDimitry Andric 5265ffd83dbSDimitry Andric static llvm::StringRef GetEncodingNameOrEmpty(const RegisterInfo ®_info) { 5275ffd83dbSDimitry Andric switch (reg_info.encoding) { 5285ffd83dbSDimitry Andric case eEncodingUint: 5295ffd83dbSDimitry Andric return "uint"; 5305ffd83dbSDimitry Andric case eEncodingSint: 5315ffd83dbSDimitry Andric return "sint"; 5325ffd83dbSDimitry Andric case eEncodingIEEE754: 5335ffd83dbSDimitry Andric return "ieee754"; 5345ffd83dbSDimitry Andric case eEncodingVector: 5355ffd83dbSDimitry Andric return "vector"; 5365ffd83dbSDimitry Andric default: 5375ffd83dbSDimitry Andric return ""; 5385ffd83dbSDimitry Andric } 5395ffd83dbSDimitry Andric } 5405ffd83dbSDimitry Andric 5415ffd83dbSDimitry Andric static llvm::StringRef GetFormatNameOrEmpty(const RegisterInfo ®_info) { 5425ffd83dbSDimitry Andric switch (reg_info.format) { 5435ffd83dbSDimitry Andric case eFormatBinary: 5445ffd83dbSDimitry Andric return "binary"; 5455ffd83dbSDimitry Andric case eFormatDecimal: 5465ffd83dbSDimitry Andric return "decimal"; 5475ffd83dbSDimitry Andric case eFormatHex: 5485ffd83dbSDimitry Andric return "hex"; 5495ffd83dbSDimitry Andric case eFormatFloat: 5505ffd83dbSDimitry Andric return "float"; 5515ffd83dbSDimitry Andric case eFormatVectorOfSInt8: 5525ffd83dbSDimitry Andric return "vector-sint8"; 5535ffd83dbSDimitry Andric case eFormatVectorOfUInt8: 5545ffd83dbSDimitry Andric return "vector-uint8"; 5555ffd83dbSDimitry Andric case eFormatVectorOfSInt16: 5565ffd83dbSDimitry Andric return "vector-sint16"; 5575ffd83dbSDimitry Andric case eFormatVectorOfUInt16: 5585ffd83dbSDimitry Andric return "vector-uint16"; 5595ffd83dbSDimitry Andric case eFormatVectorOfSInt32: 5605ffd83dbSDimitry Andric return "vector-sint32"; 5615ffd83dbSDimitry Andric case eFormatVectorOfUInt32: 5625ffd83dbSDimitry Andric return "vector-uint32"; 5635ffd83dbSDimitry Andric case eFormatVectorOfFloat32: 5645ffd83dbSDimitry Andric return "vector-float32"; 5655ffd83dbSDimitry Andric case eFormatVectorOfUInt64: 5665ffd83dbSDimitry Andric return "vector-uint64"; 5675ffd83dbSDimitry Andric case eFormatVectorOfUInt128: 5685ffd83dbSDimitry Andric return "vector-uint128"; 5695ffd83dbSDimitry Andric default: 5705ffd83dbSDimitry Andric return ""; 5715ffd83dbSDimitry Andric }; 5725ffd83dbSDimitry Andric } 5735ffd83dbSDimitry Andric 5745ffd83dbSDimitry Andric static llvm::StringRef GetKindGenericOrEmpty(const RegisterInfo ®_info) { 5755ffd83dbSDimitry Andric switch (reg_info.kinds[RegisterKind::eRegisterKindGeneric]) { 5765ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_PC: 5775ffd83dbSDimitry Andric return "pc"; 5785ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_SP: 5795ffd83dbSDimitry Andric return "sp"; 5805ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_FP: 5815ffd83dbSDimitry Andric return "fp"; 5825ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_RA: 5835ffd83dbSDimitry Andric return "ra"; 5845ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_FLAGS: 5855ffd83dbSDimitry Andric return "flags"; 5865ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG1: 5875ffd83dbSDimitry Andric return "arg1"; 5885ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG2: 5895ffd83dbSDimitry Andric return "arg2"; 5905ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG3: 5915ffd83dbSDimitry Andric return "arg3"; 5925ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG4: 5935ffd83dbSDimitry Andric return "arg4"; 5945ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG5: 5955ffd83dbSDimitry Andric return "arg5"; 5965ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG6: 5975ffd83dbSDimitry Andric return "arg6"; 5985ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG7: 5995ffd83dbSDimitry Andric return "arg7"; 6005ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG8: 6015ffd83dbSDimitry Andric return "arg8"; 6025ffd83dbSDimitry Andric default: 6035ffd83dbSDimitry Andric return ""; 6045ffd83dbSDimitry Andric } 6055ffd83dbSDimitry Andric } 6065ffd83dbSDimitry Andric 6075ffd83dbSDimitry Andric static void CollectRegNums(const uint32_t *reg_num, StreamString &response, 6085ffd83dbSDimitry Andric bool usehex) { 6095ffd83dbSDimitry Andric for (int i = 0; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { 6105ffd83dbSDimitry Andric if (i > 0) 6115ffd83dbSDimitry Andric response.PutChar(','); 6125ffd83dbSDimitry Andric if (usehex) 6135ffd83dbSDimitry Andric response.Printf("%" PRIx32, *reg_num); 6145ffd83dbSDimitry Andric else 6155ffd83dbSDimitry Andric response.Printf("%" PRIu32, *reg_num); 6165ffd83dbSDimitry Andric } 6175ffd83dbSDimitry Andric } 6185ffd83dbSDimitry Andric 6190b57cec5SDimitry Andric static void WriteRegisterValueInHexFixedWidth( 6200b57cec5SDimitry Andric StreamString &response, NativeRegisterContext ®_ctx, 6210b57cec5SDimitry Andric const RegisterInfo ®_info, const RegisterValue *reg_value_p, 6220b57cec5SDimitry Andric lldb::ByteOrder byte_order) { 6230b57cec5SDimitry Andric RegisterValue reg_value; 6240b57cec5SDimitry Andric if (!reg_value_p) { 6250b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(®_info, reg_value); 6260b57cec5SDimitry Andric if (error.Success()) 6270b57cec5SDimitry Andric reg_value_p = ®_value; 6280b57cec5SDimitry Andric // else log. 6290b57cec5SDimitry Andric } 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric if (reg_value_p) { 6320b57cec5SDimitry Andric AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(), 6330b57cec5SDimitry Andric reg_value_p->GetByteSize(), 6340b57cec5SDimitry Andric byte_order == lldb::eByteOrderLittle); 6350b57cec5SDimitry Andric } else { 6360b57cec5SDimitry Andric // Zero-out any unreadable values. 6370b57cec5SDimitry Andric if (reg_info.byte_size > 0) { 6380b57cec5SDimitry Andric std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0'); 6390b57cec5SDimitry Andric AppendHexValue(response, zeros.data(), zeros.size(), false); 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric } 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric 644e8d8bef9SDimitry Andric static llvm::Optional<json::Object> 6459dba64beSDimitry Andric GetRegistersAsJSON(NativeThreadProtocol &thread) { 64681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric NativeRegisterContext& reg_ctx = thread.GetRegisterContext(); 6490b57cec5SDimitry Andric 6509dba64beSDimitry Andric json::Object register_object; 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric #ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET 653e8d8bef9SDimitry Andric const auto expedited_regs = 654e8d8bef9SDimitry Andric reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full); 6550b57cec5SDimitry Andric #else 656e8d8bef9SDimitry Andric const auto expedited_regs = 657e8d8bef9SDimitry Andric reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Minimal); 6580b57cec5SDimitry Andric #endif 659e8d8bef9SDimitry Andric if (expedited_regs.empty()) 660e8d8bef9SDimitry Andric return llvm::None; 6610b57cec5SDimitry Andric 662e8d8bef9SDimitry Andric for (auto ®_num : expedited_regs) { 6630b57cec5SDimitry Andric const RegisterInfo *const reg_info_p = 6640b57cec5SDimitry Andric reg_ctx.GetRegisterInfoAtIndex(reg_num); 6650b57cec5SDimitry Andric if (reg_info_p == nullptr) { 6669dba64beSDimitry Andric LLDB_LOGF(log, 6670b57cec5SDimitry Andric "%s failed to get register info for register index %" PRIu32, 6680b57cec5SDimitry Andric __FUNCTION__, reg_num); 6690b57cec5SDimitry Andric continue; 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric if (reg_info_p->value_regs != nullptr) 6730b57cec5SDimitry Andric continue; // Only expedite registers that are not contained in other 6740b57cec5SDimitry Andric // registers. 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric RegisterValue reg_value; 6770b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); 6780b57cec5SDimitry Andric if (error.Fail()) { 6799dba64beSDimitry Andric LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s", 6800b57cec5SDimitry Andric __FUNCTION__, 6810b57cec5SDimitry Andric reg_info_p->name ? reg_info_p->name : "<unnamed-register>", 6820b57cec5SDimitry Andric reg_num, error.AsCString()); 6830b57cec5SDimitry Andric continue; 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric StreamString stream; 6870b57cec5SDimitry Andric WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p, 6880b57cec5SDimitry Andric ®_value, lldb::eByteOrderBig); 6890b57cec5SDimitry Andric 6909dba64beSDimitry Andric register_object.try_emplace(llvm::to_string(reg_num), 6919dba64beSDimitry Andric stream.GetString().str()); 6920b57cec5SDimitry Andric } 6930b57cec5SDimitry Andric 6949dba64beSDimitry Andric return register_object; 6950b57cec5SDimitry Andric } 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric static const char *GetStopReasonString(StopReason stop_reason) { 6980b57cec5SDimitry Andric switch (stop_reason) { 6990b57cec5SDimitry Andric case eStopReasonTrace: 7000b57cec5SDimitry Andric return "trace"; 7010b57cec5SDimitry Andric case eStopReasonBreakpoint: 7020b57cec5SDimitry Andric return "breakpoint"; 7030b57cec5SDimitry Andric case eStopReasonWatchpoint: 7040b57cec5SDimitry Andric return "watchpoint"; 7050b57cec5SDimitry Andric case eStopReasonSignal: 7060b57cec5SDimitry Andric return "signal"; 7070b57cec5SDimitry Andric case eStopReasonException: 7080b57cec5SDimitry Andric return "exception"; 7090b57cec5SDimitry Andric case eStopReasonExec: 7100b57cec5SDimitry Andric return "exec"; 711fe6060f1SDimitry Andric case eStopReasonProcessorTrace: 712fe6060f1SDimitry Andric return "processor trace"; 713fe6060f1SDimitry Andric case eStopReasonFork: 714fe6060f1SDimitry Andric return "fork"; 715fe6060f1SDimitry Andric case eStopReasonVFork: 716fe6060f1SDimitry Andric return "vfork"; 717fe6060f1SDimitry Andric case eStopReasonVForkDone: 718fe6060f1SDimitry Andric return "vforkdone"; 7190b57cec5SDimitry Andric case eStopReasonInstrumentation: 7200b57cec5SDimitry Andric case eStopReasonInvalid: 7210b57cec5SDimitry Andric case eStopReasonPlanComplete: 7220b57cec5SDimitry Andric case eStopReasonThreadExiting: 7230b57cec5SDimitry Andric case eStopReasonNone: 7240b57cec5SDimitry Andric break; // ignored 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric return nullptr; 7270b57cec5SDimitry Andric } 7280b57cec5SDimitry Andric 7299dba64beSDimitry Andric static llvm::Expected<json::Array> 7309dba64beSDimitry Andric GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) { 73181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 7320b57cec5SDimitry Andric 7339dba64beSDimitry Andric json::Array threads_array; 7340b57cec5SDimitry Andric 7350b57cec5SDimitry Andric // Ensure we can get info on the given thread. 73681ad6265SDimitry Andric for (NativeThreadProtocol &thread : process.Threads()) { 73781ad6265SDimitry Andric lldb::tid_t tid = thread.GetID(); 7380b57cec5SDimitry Andric // Grab the reason this thread stopped. 7390b57cec5SDimitry Andric struct ThreadStopInfo tid_stop_info; 7400b57cec5SDimitry Andric std::string description; 74181ad6265SDimitry Andric if (!thread.GetStopReason(tid_stop_info, description)) 7429dba64beSDimitry Andric return llvm::make_error<llvm::StringError>( 7439dba64beSDimitry Andric "failed to get stop reason", llvm::inconvertibleErrorCode()); 7440b57cec5SDimitry Andric 74581ad6265SDimitry Andric const int signum = tid_stop_info.signo; 7460b57cec5SDimitry Andric if (log) { 7479dba64beSDimitry Andric LLDB_LOGF(log, 7489dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 7490b57cec5SDimitry Andric " tid %" PRIu64 7500b57cec5SDimitry Andric " got signal signo = %d, reason = %d, exc_type = %" PRIu64, 7510b57cec5SDimitry Andric __FUNCTION__, process.GetID(), tid, signum, 7520b57cec5SDimitry Andric tid_stop_info.reason, tid_stop_info.details.exception.type); 7530b57cec5SDimitry Andric } 7540b57cec5SDimitry Andric 7559dba64beSDimitry Andric json::Object thread_obj; 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric if (!abridged) { 75881ad6265SDimitry Andric if (llvm::Optional<json::Object> registers = GetRegistersAsJSON(thread)) 7599dba64beSDimitry Andric thread_obj.try_emplace("registers", std::move(*registers)); 7600b57cec5SDimitry Andric } 7610b57cec5SDimitry Andric 7629dba64beSDimitry Andric thread_obj.try_emplace("tid", static_cast<int64_t>(tid)); 7639dba64beSDimitry Andric 7640b57cec5SDimitry Andric if (signum != 0) 7659dba64beSDimitry Andric thread_obj.try_emplace("signal", signum); 7660b57cec5SDimitry Andric 76781ad6265SDimitry Andric const std::string thread_name = thread.GetName(); 7680b57cec5SDimitry Andric if (!thread_name.empty()) 7699dba64beSDimitry Andric thread_obj.try_emplace("name", thread_name); 7700b57cec5SDimitry Andric 7719dba64beSDimitry Andric const char *stop_reason = GetStopReasonString(tid_stop_info.reason); 7729dba64beSDimitry Andric if (stop_reason) 7739dba64beSDimitry Andric thread_obj.try_emplace("reason", stop_reason); 7740b57cec5SDimitry Andric 7750b57cec5SDimitry Andric if (!description.empty()) 7769dba64beSDimitry Andric thread_obj.try_emplace("description", description); 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric if ((tid_stop_info.reason == eStopReasonException) && 7790b57cec5SDimitry Andric tid_stop_info.details.exception.type) { 7809dba64beSDimitry Andric thread_obj.try_emplace( 7819dba64beSDimitry Andric "metype", static_cast<int64_t>(tid_stop_info.details.exception.type)); 7820b57cec5SDimitry Andric 7839dba64beSDimitry Andric json::Array medata_array; 7840b57cec5SDimitry Andric for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; 7850b57cec5SDimitry Andric ++i) { 7869dba64beSDimitry Andric medata_array.push_back( 7879dba64beSDimitry Andric static_cast<int64_t>(tid_stop_info.details.exception.data[i])); 7880b57cec5SDimitry Andric } 7899dba64beSDimitry Andric thread_obj.try_emplace("medata", std::move(medata_array)); 7900b57cec5SDimitry Andric } 7919dba64beSDimitry Andric threads_array.push_back(std::move(thread_obj)); 7920b57cec5SDimitry Andric } 7939dba64beSDimitry Andric return threads_array; 7940b57cec5SDimitry Andric } 7950b57cec5SDimitry Andric 79681ad6265SDimitry Andric StreamString 79781ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::PrepareStopReplyPacketForThread( 79881ad6265SDimitry Andric NativeThreadProtocol &thread) { 79981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 8000b57cec5SDimitry Andric 80181ad6265SDimitry Andric NativeProcessProtocol &process = thread.GetProcess(); 8020b57cec5SDimitry Andric 80381ad6265SDimitry Andric LLDB_LOG(log, "preparing packet for pid {0} tid {1}", process.GetID(), 80481ad6265SDimitry Andric thread.GetID()); 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric // Grab the reason this thread stopped. 80781ad6265SDimitry Andric StreamString response; 8080b57cec5SDimitry Andric struct ThreadStopInfo tid_stop_info; 8090b57cec5SDimitry Andric std::string description; 81081ad6265SDimitry Andric if (!thread.GetStopReason(tid_stop_info, description)) 81181ad6265SDimitry Andric return response; 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric // FIXME implement register handling for exec'd inferiors. 8140b57cec5SDimitry Andric // if (tid_stop_info.reason == eStopReasonExec) { 8150b57cec5SDimitry Andric // const bool force = true; 8160b57cec5SDimitry Andric // InitializeRegisters(force); 8170b57cec5SDimitry Andric // } 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric // Output the T packet with the thread 8200b57cec5SDimitry Andric response.PutChar('T'); 82181ad6265SDimitry Andric int signum = tid_stop_info.signo; 8220b57cec5SDimitry Andric LLDB_LOG( 8230b57cec5SDimitry Andric log, 8240b57cec5SDimitry Andric "pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}", 82581ad6265SDimitry Andric process.GetID(), thread.GetID(), signum, int(tid_stop_info.reason), 8260b57cec5SDimitry Andric tid_stop_info.details.exception.type); 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andric // Print the signal number. 8290b57cec5SDimitry Andric response.PutHex8(signum & 0xff); 8300b57cec5SDimitry Andric 83181ad6265SDimitry Andric // Include the (pid and) tid. 83281ad6265SDimitry Andric response.PutCString("thread:"); 83381ad6265SDimitry Andric AppendThreadIDToResponse(response, process.GetID(), thread.GetID()); 83481ad6265SDimitry Andric response.PutChar(';'); 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric // Include the thread name if there is one. 83781ad6265SDimitry Andric const std::string thread_name = thread.GetName(); 8380b57cec5SDimitry Andric if (!thread_name.empty()) { 8390b57cec5SDimitry Andric size_t thread_name_len = thread_name.length(); 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric if (::strcspn(thread_name.c_str(), "$#+-;:") == thread_name_len) { 8420b57cec5SDimitry Andric response.PutCString("name:"); 8430b57cec5SDimitry Andric response.PutCString(thread_name); 8440b57cec5SDimitry Andric } else { 8450b57cec5SDimitry Andric // The thread name contains special chars, send as hex bytes. 8460b57cec5SDimitry Andric response.PutCString("hexname:"); 8470b57cec5SDimitry Andric response.PutStringAsRawHex8(thread_name); 8480b57cec5SDimitry Andric } 8490b57cec5SDimitry Andric response.PutChar(';'); 8500b57cec5SDimitry Andric } 8510b57cec5SDimitry Andric 8520b57cec5SDimitry Andric // If a 'QListThreadsInStopReply' was sent to enable this feature, we will 8530b57cec5SDimitry Andric // send all thread IDs back in the "threads" key whose value is a list of hex 8540b57cec5SDimitry Andric // thread IDs separated by commas: 8550b57cec5SDimitry Andric // "threads:10a,10b,10c;" 8560b57cec5SDimitry Andric // This will save the debugger from having to send a pair of qfThreadInfo and 8570b57cec5SDimitry Andric // qsThreadInfo packets, but it also might take a lot of room in the stop 8580b57cec5SDimitry Andric // reply packet, so it must be enabled only on systems where there are no 8590b57cec5SDimitry Andric // limits on packet lengths. 8600b57cec5SDimitry Andric if (m_list_threads_in_stop_reply) { 8610b57cec5SDimitry Andric response.PutCString("threads:"); 8620b57cec5SDimitry Andric 86381ad6265SDimitry Andric uint32_t thread_num = 0; 86481ad6265SDimitry Andric for (NativeThreadProtocol &listed_thread : process.Threads()) { 86581ad6265SDimitry Andric if (thread_num > 0) 8660b57cec5SDimitry Andric response.PutChar(','); 86781ad6265SDimitry Andric response.Printf("%" PRIx64, listed_thread.GetID()); 86881ad6265SDimitry Andric ++thread_num; 8690b57cec5SDimitry Andric } 8700b57cec5SDimitry Andric response.PutChar(';'); 8710b57cec5SDimitry Andric 8720b57cec5SDimitry Andric // Include JSON info that describes the stop reason for any threads that 8730b57cec5SDimitry Andric // actually have stop reasons. We use the new "jstopinfo" key whose values 8740b57cec5SDimitry Andric // is hex ascii JSON that contains the thread IDs thread stop info only for 8750b57cec5SDimitry Andric // threads that have stop reasons. Only send this if we have more than one 8760b57cec5SDimitry Andric // thread otherwise this packet has all the info it needs. 87781ad6265SDimitry Andric if (thread_num > 1) { 8780b57cec5SDimitry Andric const bool threads_with_valid_stop_info_only = true; 8799dba64beSDimitry Andric llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo( 880fe6060f1SDimitry Andric *m_current_process, threads_with_valid_stop_info_only); 8819dba64beSDimitry Andric if (threads_info) { 8820b57cec5SDimitry Andric response.PutCString("jstopinfo:"); 8830b57cec5SDimitry Andric StreamString unescaped_response; 8849dba64beSDimitry Andric unescaped_response.AsRawOstream() << std::move(*threads_info); 8850b57cec5SDimitry Andric response.PutStringAsRawHex8(unescaped_response.GetData()); 8860b57cec5SDimitry Andric response.PutChar(';'); 8879dba64beSDimitry Andric } else { 888480093f4SDimitry Andric LLDB_LOG_ERROR(log, threads_info.takeError(), 889480093f4SDimitry Andric "failed to prepare a jstopinfo field for pid {1}: {0}", 89081ad6265SDimitry Andric process.GetID()); 8919dba64beSDimitry Andric } 8920b57cec5SDimitry Andric } 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric response.PutCString("thread-pcs"); 8950b57cec5SDimitry Andric char delimiter = ':'; 89681ad6265SDimitry Andric for (NativeThreadProtocol &thread : process.Threads()) { 89781ad6265SDimitry Andric NativeRegisterContext ®_ctx = thread.GetRegisterContext(); 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber( 9000b57cec5SDimitry Andric eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 9010b57cec5SDimitry Andric const RegisterInfo *const reg_info_p = 9020b57cec5SDimitry Andric reg_ctx.GetRegisterInfoAtIndex(reg_to_read); 9030b57cec5SDimitry Andric 9040b57cec5SDimitry Andric RegisterValue reg_value; 9050b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); 9060b57cec5SDimitry Andric if (error.Fail()) { 9079dba64beSDimitry Andric LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s", 9080b57cec5SDimitry Andric __FUNCTION__, 9099dba64beSDimitry Andric reg_info_p->name ? reg_info_p->name : "<unnamed-register>", 9100b57cec5SDimitry Andric reg_to_read, error.AsCString()); 9110b57cec5SDimitry Andric continue; 9120b57cec5SDimitry Andric } 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric response.PutChar(delimiter); 9150b57cec5SDimitry Andric delimiter = ','; 9160b57cec5SDimitry Andric WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p, 9170b57cec5SDimitry Andric ®_value, endian::InlHostByteOrder()); 9180b57cec5SDimitry Andric } 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric response.PutChar(';'); 9210b57cec5SDimitry Andric } 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric // 9240b57cec5SDimitry Andric // Expedite registers. 9250b57cec5SDimitry Andric // 9260b57cec5SDimitry Andric 9270b57cec5SDimitry Andric // Grab the register context. 92881ad6265SDimitry Andric NativeRegisterContext ®_ctx = thread.GetRegisterContext(); 929e8d8bef9SDimitry Andric const auto expedited_regs = 930e8d8bef9SDimitry Andric reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full); 9310b57cec5SDimitry Andric 932e8d8bef9SDimitry Andric for (auto ®_num : expedited_regs) { 9330b57cec5SDimitry Andric const RegisterInfo *const reg_info_p = 934e8d8bef9SDimitry Andric reg_ctx.GetRegisterInfoAtIndex(reg_num); 9350b57cec5SDimitry Andric // Only expediate registers that are not contained in other registers. 936e8d8bef9SDimitry Andric if (reg_info_p != nullptr && reg_info_p->value_regs == nullptr) { 9370b57cec5SDimitry Andric RegisterValue reg_value; 9380b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); 9390b57cec5SDimitry Andric if (error.Success()) { 940e8d8bef9SDimitry Andric response.Printf("%.02x:", reg_num); 9410b57cec5SDimitry Andric WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p, 9420b57cec5SDimitry Andric ®_value, lldb::eByteOrderBig); 9430b57cec5SDimitry Andric response.PutChar(';'); 9440b57cec5SDimitry Andric } else { 94581ad6265SDimitry Andric LLDB_LOGF(log, 94681ad6265SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to read " 9470b57cec5SDimitry Andric "register '%s' index %" PRIu32 ": %s", 9480b57cec5SDimitry Andric __FUNCTION__, 9499dba64beSDimitry Andric reg_info_p->name ? reg_info_p->name : "<unnamed-register>", 950e8d8bef9SDimitry Andric reg_num, error.AsCString()); 9510b57cec5SDimitry Andric } 9520b57cec5SDimitry Andric } 9530b57cec5SDimitry Andric } 9540b57cec5SDimitry Andric 9550b57cec5SDimitry Andric const char *reason_str = GetStopReasonString(tid_stop_info.reason); 9560b57cec5SDimitry Andric if (reason_str != nullptr) { 9570b57cec5SDimitry Andric response.Printf("reason:%s;", reason_str); 9580b57cec5SDimitry Andric } 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric if (!description.empty()) { 9610b57cec5SDimitry Andric // Description may contains special chars, send as hex bytes. 9620b57cec5SDimitry Andric response.PutCString("description:"); 9630b57cec5SDimitry Andric response.PutStringAsRawHex8(description); 9640b57cec5SDimitry Andric response.PutChar(';'); 9650b57cec5SDimitry Andric } else if ((tid_stop_info.reason == eStopReasonException) && 9660b57cec5SDimitry Andric tid_stop_info.details.exception.type) { 9670b57cec5SDimitry Andric response.PutCString("metype:"); 9680b57cec5SDimitry Andric response.PutHex64(tid_stop_info.details.exception.type); 9690b57cec5SDimitry Andric response.PutCString(";mecount:"); 9700b57cec5SDimitry Andric response.PutHex32(tid_stop_info.details.exception.data_count); 9710b57cec5SDimitry Andric response.PutChar(';'); 9720b57cec5SDimitry Andric 9730b57cec5SDimitry Andric for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) { 9740b57cec5SDimitry Andric response.PutCString("medata:"); 9750b57cec5SDimitry Andric response.PutHex64(tid_stop_info.details.exception.data[i]); 9760b57cec5SDimitry Andric response.PutChar(';'); 9770b57cec5SDimitry Andric } 9780b57cec5SDimitry Andric } 9790b57cec5SDimitry Andric 980fe6060f1SDimitry Andric // Include child process PID/TID for forks. 981fe6060f1SDimitry Andric if (tid_stop_info.reason == eStopReasonFork || 982fe6060f1SDimitry Andric tid_stop_info.reason == eStopReasonVFork) { 983fe6060f1SDimitry Andric assert(bool(m_extensions_supported & 984fe6060f1SDimitry Andric NativeProcessProtocol::Extension::multiprocess)); 985fe6060f1SDimitry Andric if (tid_stop_info.reason == eStopReasonFork) 986fe6060f1SDimitry Andric assert(bool(m_extensions_supported & 987fe6060f1SDimitry Andric NativeProcessProtocol::Extension::fork)); 988fe6060f1SDimitry Andric if (tid_stop_info.reason == eStopReasonVFork) 989fe6060f1SDimitry Andric assert(bool(m_extensions_supported & 990fe6060f1SDimitry Andric NativeProcessProtocol::Extension::vfork)); 991fe6060f1SDimitry Andric response.Printf("%s:p%" PRIx64 ".%" PRIx64 ";", reason_str, 992fe6060f1SDimitry Andric tid_stop_info.details.fork.child_pid, 993fe6060f1SDimitry Andric tid_stop_info.details.fork.child_tid); 994fe6060f1SDimitry Andric } 995fe6060f1SDimitry Andric 99681ad6265SDimitry Andric return response; 99781ad6265SDimitry Andric } 99881ad6265SDimitry Andric 99981ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 100081ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( 100181ad6265SDimitry Andric NativeProcessProtocol &process, lldb::tid_t tid, bool force_synchronous) { 100281ad6265SDimitry Andric // Ensure we can get info on the given thread. 100381ad6265SDimitry Andric NativeThreadProtocol *thread = process.GetThreadByID(tid); 100481ad6265SDimitry Andric if (!thread) 100581ad6265SDimitry Andric return SendErrorResponse(51); 100681ad6265SDimitry Andric 100781ad6265SDimitry Andric StreamString response = PrepareStopReplyPacketForThread(*thread); 100881ad6265SDimitry Andric if (response.Empty()) 100981ad6265SDimitry Andric return SendErrorResponse(42); 101081ad6265SDimitry Andric 101181ad6265SDimitry Andric if (m_non_stop && !force_synchronous) { 101281ad6265SDimitry Andric PacketResult ret = SendNotificationPacketNoLock( 101381ad6265SDimitry Andric "Stop", m_stop_notification_queue, response.GetString()); 101481ad6265SDimitry Andric // Queue notification events for the remaining threads. 101581ad6265SDimitry Andric EnqueueStopReplyPackets(tid); 101681ad6265SDimitry Andric return ret; 101781ad6265SDimitry Andric } 101881ad6265SDimitry Andric 10190b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 10200b57cec5SDimitry Andric } 10210b57cec5SDimitry Andric 102281ad6265SDimitry Andric void GDBRemoteCommunicationServerLLGS::EnqueueStopReplyPackets( 102381ad6265SDimitry Andric lldb::tid_t thread_to_skip) { 102481ad6265SDimitry Andric if (!m_non_stop) 102581ad6265SDimitry Andric return; 102681ad6265SDimitry Andric 102781ad6265SDimitry Andric for (NativeThreadProtocol &listed_thread : m_current_process->Threads()) { 1028fcaf7f86SDimitry Andric if (listed_thread.GetID() != thread_to_skip) { 1029fcaf7f86SDimitry Andric StreamString stop_reply = PrepareStopReplyPacketForThread(listed_thread); 1030fcaf7f86SDimitry Andric if (!stop_reply.Empty()) 1031fcaf7f86SDimitry Andric m_stop_notification_queue.push_back(stop_reply.GetString().str()); 1032fcaf7f86SDimitry Andric } 103381ad6265SDimitry Andric } 103481ad6265SDimitry Andric } 103581ad6265SDimitry Andric 10360b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( 10370b57cec5SDimitry Andric NativeProcessProtocol *process) { 10380b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 10390b57cec5SDimitry Andric 104081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 10419dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); 10420b57cec5SDimitry Andric 104381ad6265SDimitry Andric PacketResult result = SendStopReasonForState( 104481ad6265SDimitry Andric *process, StateType::eStateExited, /*force_synchronous=*/false); 10450b57cec5SDimitry Andric if (result != PacketResult::Success) { 10469dba64beSDimitry Andric LLDB_LOGF(log, 10479dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to send stop " 10480b57cec5SDimitry Andric "notification for PID %" PRIu64 ", state: eStateExited", 10490b57cec5SDimitry Andric __FUNCTION__, process->GetID()); 10500b57cec5SDimitry Andric } 10510b57cec5SDimitry Andric 105281ad6265SDimitry Andric if (m_current_process == process) 105381ad6265SDimitry Andric m_current_process = nullptr; 105481ad6265SDimitry Andric if (m_continue_process == process) 105581ad6265SDimitry Andric m_continue_process = nullptr; 105681ad6265SDimitry Andric 105781ad6265SDimitry Andric lldb::pid_t pid = process->GetID(); 105881ad6265SDimitry Andric m_mainloop.AddPendingCallback([this, pid](MainLoopBase &loop) { 1059fcaf7f86SDimitry Andric auto find_it = m_debugged_processes.find(pid); 1060fcaf7f86SDimitry Andric assert(find_it != m_debugged_processes.end()); 1061fcaf7f86SDimitry Andric bool vkilled = bool(find_it->second.flags & DebuggedProcess::Flag::vkilled); 1062fcaf7f86SDimitry Andric m_debugged_processes.erase(find_it); 106381ad6265SDimitry Andric // Terminate the main loop only if vKill has not been used. 106481ad6265SDimitry Andric // When running in non-stop mode, wait for the vStopped to clear 106581ad6265SDimitry Andric // the notification queue. 1066fcaf7f86SDimitry Andric if (m_debugged_processes.empty() && !m_non_stop && !vkilled) { 106781ad6265SDimitry Andric // Close the pipe to the inferior terminal i/o if we launched it and set 106881ad6265SDimitry Andric // one up. 10690b57cec5SDimitry Andric MaybeCloseInferiorTerminalConnection(); 10700b57cec5SDimitry Andric 10710b57cec5SDimitry Andric // We are ready to exit the debug monitor. 10720b57cec5SDimitry Andric m_exit_now = true; 107381ad6265SDimitry Andric loop.RequestTermination(); 107481ad6265SDimitry Andric } 107581ad6265SDimitry Andric }); 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( 10790b57cec5SDimitry Andric NativeProcessProtocol *process) { 10800b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 10810b57cec5SDimitry Andric 108281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 10839dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); 10840b57cec5SDimitry Andric 108581ad6265SDimitry Andric PacketResult result = SendStopReasonForState( 108681ad6265SDimitry Andric *process, StateType::eStateStopped, /*force_synchronous=*/false); 10870b57cec5SDimitry Andric if (result != PacketResult::Success) { 10889dba64beSDimitry Andric LLDB_LOGF(log, 10899dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to send stop " 10900b57cec5SDimitry Andric "notification for PID %" PRIu64 ", state: eStateExited", 10910b57cec5SDimitry Andric __FUNCTION__, process->GetID()); 10920b57cec5SDimitry Andric } 10930b57cec5SDimitry Andric } 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::ProcessStateChanged( 10960b57cec5SDimitry Andric NativeProcessProtocol *process, lldb::StateType state) { 10970b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 109881ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 10990b57cec5SDimitry Andric if (log) { 11009dba64beSDimitry Andric LLDB_LOGF(log, 11019dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s called with " 11020b57cec5SDimitry Andric "NativeProcessProtocol pid %" PRIu64 ", state: %s", 11030b57cec5SDimitry Andric __FUNCTION__, process->GetID(), StateAsCString(state)); 11040b57cec5SDimitry Andric } 11050b57cec5SDimitry Andric 11060b57cec5SDimitry Andric switch (state) { 11070b57cec5SDimitry Andric case StateType::eStateRunning: 11080b57cec5SDimitry Andric break; 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric case StateType::eStateStopped: 11110b57cec5SDimitry Andric // Make sure we get all of the pending stdout/stderr from the inferior and 11120b57cec5SDimitry Andric // send it to the lldb host before we send the state change notification 11130b57cec5SDimitry Andric SendProcessOutput(); 11140b57cec5SDimitry Andric // Then stop the forwarding, so that any late output (see llvm.org/pr25652) 11150b57cec5SDimitry Andric // does not interfere with our protocol. 1116fcaf7f86SDimitry Andric if (!m_non_stop) 11170b57cec5SDimitry Andric StopSTDIOForwarding(); 11180b57cec5SDimitry Andric HandleInferiorState_Stopped(process); 11190b57cec5SDimitry Andric break; 11200b57cec5SDimitry Andric 11210b57cec5SDimitry Andric case StateType::eStateExited: 11220b57cec5SDimitry Andric // Same as above 11230b57cec5SDimitry Andric SendProcessOutput(); 1124fcaf7f86SDimitry Andric if (!m_non_stop) 11250b57cec5SDimitry Andric StopSTDIOForwarding(); 11260b57cec5SDimitry Andric HandleInferiorState_Exited(process); 11270b57cec5SDimitry Andric break; 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric default: 11300b57cec5SDimitry Andric if (log) { 11319dba64beSDimitry Andric LLDB_LOGF(log, 11329dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s didn't handle state " 11330b57cec5SDimitry Andric "change for pid %" PRIu64 ", new state: %s", 11340b57cec5SDimitry Andric __FUNCTION__, process->GetID(), StateAsCString(state)); 11350b57cec5SDimitry Andric } 11360b57cec5SDimitry Andric break; 11370b57cec5SDimitry Andric } 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) { 11410b57cec5SDimitry Andric ClearProcessSpecificData(); 11420b57cec5SDimitry Andric } 11430b57cec5SDimitry Andric 1144fe6060f1SDimitry Andric void GDBRemoteCommunicationServerLLGS::NewSubprocess( 1145fe6060f1SDimitry Andric NativeProcessProtocol *parent_process, 1146fe6060f1SDimitry Andric std::unique_ptr<NativeProcessProtocol> child_process) { 1147fe6060f1SDimitry Andric lldb::pid_t child_pid = child_process->GetID(); 1148fe6060f1SDimitry Andric assert(child_pid != LLDB_INVALID_PROCESS_ID); 1149fe6060f1SDimitry Andric assert(m_debugged_processes.find(child_pid) == m_debugged_processes.end()); 1150fcaf7f86SDimitry Andric m_debugged_processes.emplace( 1151fcaf7f86SDimitry Andric child_pid, 1152fcaf7f86SDimitry Andric DebuggedProcess{std::move(child_process), DebuggedProcess::Flag{}}); 1153fe6060f1SDimitry Andric } 1154fe6060f1SDimitry Andric 11550b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() { 115604eeddc0SDimitry Andric Log *log = GetLog(GDBRLog::Comm); 11570b57cec5SDimitry Andric 11580b57cec5SDimitry Andric bool interrupt = false; 11590b57cec5SDimitry Andric bool done = false; 11600b57cec5SDimitry Andric Status error; 11610b57cec5SDimitry Andric while (true) { 11620b57cec5SDimitry Andric const PacketResult result = GetPacketAndSendResponse( 11630b57cec5SDimitry Andric std::chrono::microseconds(0), error, interrupt, done); 11640b57cec5SDimitry Andric if (result == PacketResult::ErrorReplyTimeout) 11650b57cec5SDimitry Andric break; // No more packets in the queue 11660b57cec5SDimitry Andric 11670b57cec5SDimitry Andric if ((result != PacketResult::Success)) { 11689dba64beSDimitry Andric LLDB_LOGF(log, 11699dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s processing a packet " 11700b57cec5SDimitry Andric "failed: %s", 11710b57cec5SDimitry Andric __FUNCTION__, error.AsCString()); 11720b57cec5SDimitry Andric m_mainloop.RequestTermination(); 11730b57cec5SDimitry Andric break; 11740b57cec5SDimitry Andric } 11750b57cec5SDimitry Andric } 11760b57cec5SDimitry Andric } 11770b57cec5SDimitry Andric 11780b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::InitializeConnection( 11795ffd83dbSDimitry Andric std::unique_ptr<Connection> connection) { 11800b57cec5SDimitry Andric IOObjectSP read_object_sp = connection->GetReadObject(); 11815ffd83dbSDimitry Andric GDBRemoteCommunicationServer::SetConnection(std::move(connection)); 11820b57cec5SDimitry Andric 11830b57cec5SDimitry Andric Status error; 11840b57cec5SDimitry Andric m_network_handle_up = m_mainloop.RegisterReadObject( 11850b57cec5SDimitry Andric read_object_sp, [this](MainLoopBase &) { DataAvailableCallback(); }, 11860b57cec5SDimitry Andric error); 11870b57cec5SDimitry Andric return error; 11880b57cec5SDimitry Andric } 11890b57cec5SDimitry Andric 11900b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 11910b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer, 11920b57cec5SDimitry Andric uint32_t len) { 11930b57cec5SDimitry Andric if ((buffer == nullptr) || (len == 0)) { 11940b57cec5SDimitry Andric // Nothing to send. 11950b57cec5SDimitry Andric return PacketResult::Success; 11960b57cec5SDimitry Andric } 11970b57cec5SDimitry Andric 11980b57cec5SDimitry Andric StreamString response; 11990b57cec5SDimitry Andric response.PutChar('O'); 12000b57cec5SDimitry Andric response.PutBytesAsRawHex8(buffer, len); 12010b57cec5SDimitry Andric 1202fcaf7f86SDimitry Andric if (m_non_stop) 1203fcaf7f86SDimitry Andric return SendNotificationPacketNoLock("Stdio", m_stdio_notification_queue, 1204fcaf7f86SDimitry Andric response.GetString()); 12050b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 12060b57cec5SDimitry Andric } 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) { 12090b57cec5SDimitry Andric Status error; 12100b57cec5SDimitry Andric 12110b57cec5SDimitry Andric // Set up the reading/handling of process I/O 12120b57cec5SDimitry Andric std::unique_ptr<ConnectionFileDescriptor> conn_up( 12130b57cec5SDimitry Andric new ConnectionFileDescriptor(fd, true)); 12140b57cec5SDimitry Andric if (!conn_up) { 12150b57cec5SDimitry Andric error.SetErrorString("failed to create ConnectionFileDescriptor"); 12160b57cec5SDimitry Andric return error; 12170b57cec5SDimitry Andric } 12180b57cec5SDimitry Andric 12190b57cec5SDimitry Andric m_stdio_communication.SetCloseOnEOF(false); 12205ffd83dbSDimitry Andric m_stdio_communication.SetConnection(std::move(conn_up)); 12210b57cec5SDimitry Andric if (!m_stdio_communication.IsConnected()) { 12220b57cec5SDimitry Andric error.SetErrorString( 12230b57cec5SDimitry Andric "failed to set connection for inferior I/O communication"); 12240b57cec5SDimitry Andric return error; 12250b57cec5SDimitry Andric } 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric return Status(); 12280b57cec5SDimitry Andric } 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() { 12310b57cec5SDimitry Andric // Don't forward if not connected (e.g. when attaching). 12320b57cec5SDimitry Andric if (!m_stdio_communication.IsConnected()) 12330b57cec5SDimitry Andric return; 12340b57cec5SDimitry Andric 12350b57cec5SDimitry Andric Status error; 123681ad6265SDimitry Andric assert(!m_stdio_handle_up); 12370b57cec5SDimitry Andric m_stdio_handle_up = m_mainloop.RegisterReadObject( 12380b57cec5SDimitry Andric m_stdio_communication.GetConnection()->GetReadObject(), 12390b57cec5SDimitry Andric [this](MainLoopBase &) { SendProcessOutput(); }, error); 12400b57cec5SDimitry Andric 12410b57cec5SDimitry Andric if (!m_stdio_handle_up) { 12420b57cec5SDimitry Andric // Not much we can do about the failure. Log it and continue without 12430b57cec5SDimitry Andric // forwarding. 124481ad6265SDimitry Andric if (Log *log = GetLog(LLDBLog::Process)) 124581ad6265SDimitry Andric LLDB_LOG(log, "Failed to set up stdio forwarding: {0}", error); 12460b57cec5SDimitry Andric } 12470b57cec5SDimitry Andric } 12480b57cec5SDimitry Andric 12490b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() { 12500b57cec5SDimitry Andric m_stdio_handle_up.reset(); 12510b57cec5SDimitry Andric } 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SendProcessOutput() { 12540b57cec5SDimitry Andric char buffer[1024]; 12550b57cec5SDimitry Andric ConnectionStatus status; 12560b57cec5SDimitry Andric Status error; 12570b57cec5SDimitry Andric while (true) { 12580b57cec5SDimitry Andric size_t bytes_read = m_stdio_communication.Read( 12590b57cec5SDimitry Andric buffer, sizeof buffer, std::chrono::microseconds(0), status, &error); 12600b57cec5SDimitry Andric switch (status) { 12610b57cec5SDimitry Andric case eConnectionStatusSuccess: 12620b57cec5SDimitry Andric SendONotification(buffer, bytes_read); 12630b57cec5SDimitry Andric break; 12640b57cec5SDimitry Andric case eConnectionStatusLostConnection: 12650b57cec5SDimitry Andric case eConnectionStatusEndOfFile: 12660b57cec5SDimitry Andric case eConnectionStatusError: 12670b57cec5SDimitry Andric case eConnectionStatusNoConnection: 126881ad6265SDimitry Andric if (Log *log = GetLog(LLDBLog::Process)) 12699dba64beSDimitry Andric LLDB_LOGF(log, 12709dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s Stopping stdio " 12710b57cec5SDimitry Andric "forwarding as communication returned status %d (error: " 12720b57cec5SDimitry Andric "%s)", 12730b57cec5SDimitry Andric __FUNCTION__, status, error.AsCString()); 12740b57cec5SDimitry Andric m_stdio_handle_up.reset(); 12750b57cec5SDimitry Andric return; 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andric case eConnectionStatusInterrupted: 12780b57cec5SDimitry Andric case eConnectionStatusTimedOut: 12790b57cec5SDimitry Andric return; 12800b57cec5SDimitry Andric } 12810b57cec5SDimitry Andric } 12820b57cec5SDimitry Andric } 12830b57cec5SDimitry Andric 12840b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1285fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported( 12860b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 1287fe6060f1SDimitry Andric 12880b57cec5SDimitry Andric // Fail if we don't have a current process. 1289fe6060f1SDimitry Andric if (!m_current_process || 1290fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 1291fe6060f1SDimitry Andric return SendErrorResponse(Status("Process not running.")); 12920b57cec5SDimitry Andric 1293fe6060f1SDimitry Andric return SendJSONResponse(m_current_process->TraceSupported()); 12940b57cec5SDimitry Andric } 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1297fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop( 12980b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 12990b57cec5SDimitry Andric // Fail if we don't have a current process. 1300fe6060f1SDimitry Andric if (!m_current_process || 1301fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 1302fe6060f1SDimitry Andric return SendErrorResponse(Status("Process not running.")); 13030b57cec5SDimitry Andric 1304fe6060f1SDimitry Andric packet.ConsumeFront("jLLDBTraceStop:"); 1305fe6060f1SDimitry Andric Expected<TraceStopRequest> stop_request = 1306fe6060f1SDimitry Andric json::parse<TraceStopRequest>(packet.Peek(), "TraceStopRequest"); 1307fe6060f1SDimitry Andric if (!stop_request) 1308fe6060f1SDimitry Andric return SendErrorResponse(stop_request.takeError()); 13090b57cec5SDimitry Andric 1310fe6060f1SDimitry Andric if (Error err = m_current_process->TraceStop(*stop_request)) 1311fe6060f1SDimitry Andric return SendErrorResponse(std::move(err)); 13120b57cec5SDimitry Andric 13130b57cec5SDimitry Andric return SendOKResponse(); 13140b57cec5SDimitry Andric } 13150b57cec5SDimitry Andric 13160b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1317fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart( 1318e8d8bef9SDimitry Andric StringExtractorGDBRemote &packet) { 1319e8d8bef9SDimitry Andric 1320e8d8bef9SDimitry 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)) 1323e8d8bef9SDimitry Andric return SendErrorResponse(Status("Process not running.")); 1324e8d8bef9SDimitry Andric 1325fe6060f1SDimitry Andric packet.ConsumeFront("jLLDBTraceStart:"); 1326fe6060f1SDimitry Andric Expected<TraceStartRequest> request = 1327fe6060f1SDimitry Andric json::parse<TraceStartRequest>(packet.Peek(), "TraceStartRequest"); 1328fe6060f1SDimitry Andric if (!request) 1329fe6060f1SDimitry Andric return SendErrorResponse(request.takeError()); 1330e8d8bef9SDimitry Andric 1331fe6060f1SDimitry Andric if (Error err = m_current_process->TraceStart(packet.Peek(), request->type)) 1332fe6060f1SDimitry Andric return SendErrorResponse(std::move(err)); 1333e8d8bef9SDimitry Andric 1334fe6060f1SDimitry Andric return SendOKResponse(); 1335e8d8bef9SDimitry Andric } 1336e8d8bef9SDimitry Andric 1337e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 1338fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState( 13390b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 13400b57cec5SDimitry Andric 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)) 1344fe6060f1SDimitry Andric return SendErrorResponse(Status("Process not running.")); 13450b57cec5SDimitry Andric 1346fe6060f1SDimitry Andric packet.ConsumeFront("jLLDBTraceGetState:"); 1347fe6060f1SDimitry Andric Expected<TraceGetStateRequest> request = 1348fe6060f1SDimitry Andric json::parse<TraceGetStateRequest>(packet.Peek(), "TraceGetStateRequest"); 1349fe6060f1SDimitry Andric if (!request) 1350fe6060f1SDimitry Andric return SendErrorResponse(request.takeError()); 13510b57cec5SDimitry Andric 1352fe6060f1SDimitry Andric return SendJSONResponse(m_current_process->TraceGetState(request->type)); 13530b57cec5SDimitry Andric } 13540b57cec5SDimitry Andric 13550b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1356fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData( 13570b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric // Fail if we don't have a current process. 1360fe6060f1SDimitry Andric if (!m_current_process || 1361fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 1362fe6060f1SDimitry Andric return SendErrorResponse(Status("Process not running.")); 13630b57cec5SDimitry Andric 1364fe6060f1SDimitry Andric packet.ConsumeFront("jLLDBTraceGetBinaryData:"); 1365fe6060f1SDimitry Andric llvm::Expected<TraceGetBinaryDataRequest> request = 1366fe6060f1SDimitry Andric llvm::json::parse<TraceGetBinaryDataRequest>(packet.Peek(), 1367fe6060f1SDimitry Andric "TraceGetBinaryDataRequest"); 1368fe6060f1SDimitry Andric if (!request) 1369fe6060f1SDimitry Andric return SendErrorResponse(Status(request.takeError())); 13700b57cec5SDimitry Andric 1371fe6060f1SDimitry Andric if (Expected<std::vector<uint8_t>> bytes = 1372fe6060f1SDimitry Andric m_current_process->TraceGetBinaryData(*request)) { 13730b57cec5SDimitry Andric StreamGDBRemote response; 1374fe6060f1SDimitry Andric response.PutEscapedBytes(bytes->data(), bytes->size()); 1375fe6060f1SDimitry Andric return SendPacketNoLock(response.GetString()); 1376fe6060f1SDimitry Andric } else 1377fe6060f1SDimitry Andric return SendErrorResponse(bytes.takeError()); 13780b57cec5SDimitry Andric } 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 13810b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo( 13820b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 13830b57cec5SDimitry Andric // Fail if we don't have a current process. 1384fe6060f1SDimitry Andric if (!m_current_process || 1385fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 13860b57cec5SDimitry Andric return SendErrorResponse(68); 13870b57cec5SDimitry Andric 1388fe6060f1SDimitry Andric lldb::pid_t pid = m_current_process->GetID(); 13890b57cec5SDimitry Andric 13900b57cec5SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 13910b57cec5SDimitry Andric return SendErrorResponse(1); 13920b57cec5SDimitry Andric 13930b57cec5SDimitry Andric ProcessInstanceInfo proc_info; 13940b57cec5SDimitry Andric if (!Host::GetProcessInfo(pid, proc_info)) 13950b57cec5SDimitry Andric return SendErrorResponse(1); 13960b57cec5SDimitry Andric 13970b57cec5SDimitry Andric StreamString response; 13980b57cec5SDimitry Andric CreateProcessInfoResponse_DebugServerStyle(proc_info, response); 13990b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 14000b57cec5SDimitry Andric } 14010b57cec5SDimitry Andric 14020b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 14030b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) { 14040b57cec5SDimitry Andric // Fail if we don't have a current process. 1405fe6060f1SDimitry Andric if (!m_current_process || 1406fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 14070b57cec5SDimitry Andric return SendErrorResponse(68); 14080b57cec5SDimitry Andric 14090b57cec5SDimitry Andric // Make sure we set the current thread so g and p packets return the data the 14100b57cec5SDimitry Andric // gdb will expect. 1411fe6060f1SDimitry Andric lldb::tid_t tid = m_current_process->GetCurrentThreadID(); 14120b57cec5SDimitry Andric SetCurrentThreadID(tid); 14130b57cec5SDimitry Andric 1414fe6060f1SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); 14150b57cec5SDimitry Andric if (!thread) 14160b57cec5SDimitry Andric return SendErrorResponse(69); 14170b57cec5SDimitry Andric 14180b57cec5SDimitry Andric StreamString response; 141981ad6265SDimitry Andric response.PutCString("QC"); 142081ad6265SDimitry Andric AppendThreadIDToResponse(response, m_current_process->GetID(), 142181ad6265SDimitry Andric thread->GetID()); 14220b57cec5SDimitry Andric 14230b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 14240b57cec5SDimitry Andric } 14250b57cec5SDimitry Andric 14260b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 14270b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) { 142881ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 14290b57cec5SDimitry Andric 1430fcaf7f86SDimitry Andric if (!m_non_stop) 14310b57cec5SDimitry Andric StopSTDIOForwarding(); 14320b57cec5SDimitry Andric 143381ad6265SDimitry Andric if (m_debugged_processes.empty()) { 14340b57cec5SDimitry Andric LLDB_LOG(log, "No debugged process found."); 14350b57cec5SDimitry Andric return PacketResult::Success; 14360b57cec5SDimitry Andric } 14370b57cec5SDimitry Andric 143881ad6265SDimitry Andric for (auto it = m_debugged_processes.begin(); it != m_debugged_processes.end(); 143981ad6265SDimitry Andric ++it) { 144081ad6265SDimitry Andric LLDB_LOG(log, "Killing process {0}", it->first); 1441fcaf7f86SDimitry Andric Status error = it->second.process_up->Kill(); 14420b57cec5SDimitry Andric if (error.Fail()) 144381ad6265SDimitry Andric LLDB_LOG(log, "Failed to kill debugged process {0}: {1}", it->first, 144481ad6265SDimitry Andric error); 144581ad6265SDimitry Andric } 14460b57cec5SDimitry Andric 144781ad6265SDimitry Andric // The response to kill packet is undefined per the spec. LLDB 144881ad6265SDimitry Andric // follows the same rules as for continue packets, i.e. no response 144981ad6265SDimitry Andric // in all-stop mode, and "OK" in non-stop mode; in both cases this 145081ad6265SDimitry Andric // is followed by the actual stop reason. 145181ad6265SDimitry Andric return SendContinueSuccessResponse(); 145281ad6265SDimitry Andric } 145381ad6265SDimitry Andric 145481ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 145581ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vKill( 145681ad6265SDimitry Andric StringExtractorGDBRemote &packet) { 1457fcaf7f86SDimitry Andric if (!m_non_stop) 145881ad6265SDimitry Andric StopSTDIOForwarding(); 145981ad6265SDimitry Andric 146081ad6265SDimitry Andric packet.SetFilePos(6); // vKill; 146181ad6265SDimitry Andric uint32_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); 146281ad6265SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 146381ad6265SDimitry Andric return SendIllFormedResponse(packet, 146481ad6265SDimitry Andric "vKill failed to parse the process id"); 146581ad6265SDimitry Andric 146681ad6265SDimitry Andric auto it = m_debugged_processes.find(pid); 146781ad6265SDimitry Andric if (it == m_debugged_processes.end()) 146881ad6265SDimitry Andric return SendErrorResponse(42); 146981ad6265SDimitry Andric 1470fcaf7f86SDimitry Andric Status error = it->second.process_up->Kill(); 147181ad6265SDimitry Andric if (error.Fail()) 147281ad6265SDimitry Andric return SendErrorResponse(error.ToError()); 147381ad6265SDimitry Andric 147481ad6265SDimitry Andric // OK response is sent when the process dies. 1475fcaf7f86SDimitry Andric it->second.flags |= DebuggedProcess::Flag::vkilled; 14760b57cec5SDimitry Andric return PacketResult::Success; 14770b57cec5SDimitry Andric } 14780b57cec5SDimitry Andric 14790b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 14800b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR( 14810b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 14820b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetDisableASLR:")); 14830b57cec5SDimitry Andric if (packet.GetU32(0)) 14840b57cec5SDimitry Andric m_process_launch_info.GetFlags().Set(eLaunchFlagDisableASLR); 14850b57cec5SDimitry Andric else 14860b57cec5SDimitry Andric m_process_launch_info.GetFlags().Clear(eLaunchFlagDisableASLR); 14870b57cec5SDimitry Andric return SendOKResponse(); 14880b57cec5SDimitry Andric } 14890b57cec5SDimitry Andric 14900b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 14910b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir( 14920b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 14930b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetWorkingDir:")); 14940b57cec5SDimitry Andric std::string path; 14950b57cec5SDimitry Andric packet.GetHexByteString(path); 14960b57cec5SDimitry Andric m_process_launch_info.SetWorkingDirectory(FileSpec(path)); 14970b57cec5SDimitry Andric return SendOKResponse(); 14980b57cec5SDimitry Andric } 14990b57cec5SDimitry Andric 15000b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 15010b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir( 15020b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 15030b57cec5SDimitry Andric FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()}; 15040b57cec5SDimitry Andric if (working_dir) { 15050b57cec5SDimitry Andric StreamString response; 15060b57cec5SDimitry Andric response.PutStringAsRawHex8(working_dir.GetCString()); 15070b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 15080b57cec5SDimitry Andric } 15090b57cec5SDimitry Andric 15100b57cec5SDimitry Andric return SendErrorResponse(14); 15110b57cec5SDimitry Andric } 15120b57cec5SDimitry Andric 15130b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1514fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported( 1515fe6060f1SDimitry Andric StringExtractorGDBRemote &packet) { 1516fe6060f1SDimitry Andric m_thread_suffix_supported = true; 1517fe6060f1SDimitry Andric return SendOKResponse(); 1518fe6060f1SDimitry Andric } 1519fe6060f1SDimitry Andric 1520fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult 1521fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply( 1522fe6060f1SDimitry Andric StringExtractorGDBRemote &packet) { 1523fe6060f1SDimitry Andric m_list_threads_in_stop_reply = true; 1524fe6060f1SDimitry Andric return SendOKResponse(); 1525fe6060f1SDimitry Andric } 1526fe6060f1SDimitry Andric 1527fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult 1528fcaf7f86SDimitry Andric GDBRemoteCommunicationServerLLGS::ResumeProcess( 1529fcaf7f86SDimitry Andric NativeProcessProtocol &process, const ResumeActionList &actions) { 1530fcaf7f86SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 1531fcaf7f86SDimitry Andric 1532fcaf7f86SDimitry Andric // In non-stop protocol mode, the process could be running already. 1533fcaf7f86SDimitry Andric // We do not support resuming threads independently, so just error out. 1534fcaf7f86SDimitry Andric if (!process.CanResume()) { 1535fcaf7f86SDimitry Andric LLDB_LOG(log, "process {0} cannot be resumed (state={1})", process.GetID(), 1536fcaf7f86SDimitry Andric process.GetState()); 1537fcaf7f86SDimitry Andric return SendErrorResponse(0x37); 1538fcaf7f86SDimitry Andric } 1539fcaf7f86SDimitry Andric 1540fcaf7f86SDimitry Andric Status error = process.Resume(actions); 1541fcaf7f86SDimitry Andric if (error.Fail()) { 1542fcaf7f86SDimitry Andric LLDB_LOG(log, "process {0} failed to resume: {1}", process.GetID(), error); 1543fcaf7f86SDimitry Andric return SendErrorResponse(GDBRemoteServerError::eErrorResume); 1544fcaf7f86SDimitry Andric } 1545fcaf7f86SDimitry Andric 1546fcaf7f86SDimitry Andric LLDB_LOG(log, "process {0} resumed", process.GetID()); 1547fcaf7f86SDimitry Andric 1548fcaf7f86SDimitry Andric return PacketResult::Success; 1549fcaf7f86SDimitry Andric } 1550fcaf7f86SDimitry Andric 1551fcaf7f86SDimitry Andric GDBRemoteCommunication::PacketResult 15520b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { 155381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 15549dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); 15550b57cec5SDimitry Andric 15560b57cec5SDimitry Andric // Ensure we have a native process. 1557fe6060f1SDimitry Andric if (!m_continue_process) { 15589dba64beSDimitry Andric LLDB_LOGF(log, 15599dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s no debugged process " 15600b57cec5SDimitry Andric "shared pointer", 15610b57cec5SDimitry Andric __FUNCTION__); 15620b57cec5SDimitry Andric return SendErrorResponse(0x36); 15630b57cec5SDimitry Andric } 15640b57cec5SDimitry Andric 15650b57cec5SDimitry Andric // Pull out the signal number. 15660b57cec5SDimitry Andric packet.SetFilePos(::strlen("C")); 15670b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) { 15680b57cec5SDimitry Andric // Shouldn't be using a C without a signal. 15690b57cec5SDimitry Andric return SendIllFormedResponse(packet, "C packet specified without signal."); 15700b57cec5SDimitry Andric } 15710b57cec5SDimitry Andric const uint32_t signo = 15720b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 15730b57cec5SDimitry Andric if (signo == std::numeric_limits<uint32_t>::max()) 15740b57cec5SDimitry Andric return SendIllFormedResponse(packet, "failed to parse signal number"); 15750b57cec5SDimitry Andric 15760b57cec5SDimitry Andric // Handle optional continue address. 15770b57cec5SDimitry Andric if (packet.GetBytesLeft() > 0) { 15780b57cec5SDimitry Andric // FIXME add continue at address support for $C{signo}[;{continue-address}]. 15790b57cec5SDimitry Andric if (*packet.Peek() == ';') 15809dba64beSDimitry Andric return SendUnimplementedResponse(packet.GetStringRef().data()); 15810b57cec5SDimitry Andric else 15820b57cec5SDimitry Andric return SendIllFormedResponse( 15830b57cec5SDimitry Andric packet, "unexpected content after $C{signal-number}"); 15840b57cec5SDimitry Andric } 15850b57cec5SDimitry Andric 1586fcaf7f86SDimitry Andric // In non-stop protocol mode, the process could be running already. 1587fcaf7f86SDimitry Andric // We do not support resuming threads independently, so just error out. 1588fcaf7f86SDimitry Andric if (!m_continue_process->CanResume()) { 1589fcaf7f86SDimitry Andric LLDB_LOG(log, "process cannot be resumed (state={0})", 1590fcaf7f86SDimitry Andric m_continue_process->GetState()); 1591fcaf7f86SDimitry Andric return SendErrorResponse(0x37); 1592fcaf7f86SDimitry Andric } 1593fcaf7f86SDimitry Andric 15949dba64beSDimitry Andric ResumeActionList resume_actions(StateType::eStateRunning, 15959dba64beSDimitry Andric LLDB_INVALID_SIGNAL_NUMBER); 15960b57cec5SDimitry Andric Status error; 15970b57cec5SDimitry Andric 15980b57cec5SDimitry Andric // We have two branches: what to do if a continue thread is specified (in 15990b57cec5SDimitry Andric // which case we target sending the signal to that thread), or when we don't 16000b57cec5SDimitry Andric // have a continue thread set (in which case we send a signal to the 16010b57cec5SDimitry Andric // process). 16020b57cec5SDimitry Andric 16030b57cec5SDimitry Andric // TODO discuss with Greg Clayton, make sure this makes sense. 16040b57cec5SDimitry Andric 16050b57cec5SDimitry Andric lldb::tid_t signal_tid = GetContinueThreadID(); 16060b57cec5SDimitry Andric if (signal_tid != LLDB_INVALID_THREAD_ID) { 16070b57cec5SDimitry Andric // The resume action for the continue thread (or all threads if a continue 16080b57cec5SDimitry Andric // thread is not set). 16090b57cec5SDimitry Andric ResumeAction action = {GetContinueThreadID(), StateType::eStateRunning, 16100b57cec5SDimitry Andric static_cast<int>(signo)}; 16110b57cec5SDimitry Andric 16120b57cec5SDimitry Andric // Add the action for the continue thread (or all threads when the continue 16130b57cec5SDimitry Andric // thread isn't present). 16140b57cec5SDimitry Andric resume_actions.Append(action); 16150b57cec5SDimitry Andric } else { 16160b57cec5SDimitry Andric // Send the signal to the process since we weren't targeting a specific 16170b57cec5SDimitry Andric // continue thread with the signal. 1618fe6060f1SDimitry Andric error = m_continue_process->Signal(signo); 16190b57cec5SDimitry Andric if (error.Fail()) { 16200b57cec5SDimitry Andric LLDB_LOG(log, "failed to send signal for process {0}: {1}", 1621fe6060f1SDimitry Andric m_continue_process->GetID(), error); 16220b57cec5SDimitry Andric 16230b57cec5SDimitry Andric return SendErrorResponse(0x52); 16240b57cec5SDimitry Andric } 16250b57cec5SDimitry Andric } 16260b57cec5SDimitry Andric 1627fcaf7f86SDimitry Andric // NB: this checks CanResume() twice but using a single code path for 1628fcaf7f86SDimitry Andric // resuming still seems worth it. 1629fcaf7f86SDimitry Andric PacketResult resume_res = ResumeProcess(*m_continue_process, resume_actions); 1630fcaf7f86SDimitry Andric if (resume_res != PacketResult::Success) 1631fcaf7f86SDimitry Andric return resume_res; 16320b57cec5SDimitry Andric 163381ad6265SDimitry Andric // Don't send an "OK" packet, except in non-stop mode; 163481ad6265SDimitry Andric // otherwise, the response is the stopped/exited message. 163581ad6265SDimitry Andric return SendContinueSuccessResponse(); 16360b57cec5SDimitry Andric } 16370b57cec5SDimitry Andric 16380b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 16390b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { 164081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 16419dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); 16420b57cec5SDimitry Andric 16430b57cec5SDimitry Andric packet.SetFilePos(packet.GetFilePos() + ::strlen("c")); 16440b57cec5SDimitry Andric 16450b57cec5SDimitry Andric // For now just support all continue. 16460b57cec5SDimitry Andric const bool has_continue_address = (packet.GetBytesLeft() > 0); 16470b57cec5SDimitry Andric if (has_continue_address) { 16480b57cec5SDimitry Andric LLDB_LOG(log, "not implemented for c[address] variant [{0} remains]", 16490b57cec5SDimitry Andric packet.Peek()); 16509dba64beSDimitry Andric return SendUnimplementedResponse(packet.GetStringRef().data()); 16510b57cec5SDimitry Andric } 16520b57cec5SDimitry Andric 16530b57cec5SDimitry Andric // Ensure we have a native process. 1654fe6060f1SDimitry Andric if (!m_continue_process) { 16559dba64beSDimitry Andric LLDB_LOGF(log, 16569dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s no debugged process " 16570b57cec5SDimitry Andric "shared pointer", 16580b57cec5SDimitry Andric __FUNCTION__); 16590b57cec5SDimitry Andric return SendErrorResponse(0x36); 16600b57cec5SDimitry Andric } 16610b57cec5SDimitry Andric 16620b57cec5SDimitry Andric // Build the ResumeActionList 16639dba64beSDimitry Andric ResumeActionList actions(StateType::eStateRunning, 16649dba64beSDimitry Andric LLDB_INVALID_SIGNAL_NUMBER); 16650b57cec5SDimitry Andric 1666fcaf7f86SDimitry Andric PacketResult resume_res = ResumeProcess(*m_continue_process, actions); 1667fcaf7f86SDimitry Andric if (resume_res != PacketResult::Success) 1668fcaf7f86SDimitry Andric return resume_res; 166981ad6265SDimitry Andric 167081ad6265SDimitry Andric return SendContinueSuccessResponse(); 16710b57cec5SDimitry Andric } 16720b57cec5SDimitry Andric 16730b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 16740b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vCont_actions( 16750b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 16760b57cec5SDimitry Andric StreamString response; 167781ad6265SDimitry Andric response.Printf("vCont;c;C;s;S;t"); 16780b57cec5SDimitry Andric 16790b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 16800b57cec5SDimitry Andric } 16810b57cec5SDimitry Andric 1682fcaf7f86SDimitry Andric static bool ResumeActionListStopsAllThreads(ResumeActionList &actions) { 1683fcaf7f86SDimitry Andric // We're doing a stop-all if and only if our only action is a "t" for all 1684fcaf7f86SDimitry Andric // threads. 1685fcaf7f86SDimitry Andric if (const ResumeAction *default_action = 1686fcaf7f86SDimitry Andric actions.GetActionForThread(LLDB_INVALID_THREAD_ID, false)) { 1687fcaf7f86SDimitry Andric if (default_action->state == eStateSuspended && actions.GetSize() == 1) 1688fcaf7f86SDimitry Andric return true; 1689fcaf7f86SDimitry Andric } 1690fcaf7f86SDimitry Andric 1691fcaf7f86SDimitry Andric return false; 1692fcaf7f86SDimitry Andric } 1693fcaf7f86SDimitry Andric 16940b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 16950b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vCont( 16960b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 169781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 16989dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s handling vCont packet", 16990b57cec5SDimitry Andric __FUNCTION__); 17000b57cec5SDimitry Andric 17010b57cec5SDimitry Andric packet.SetFilePos(::strlen("vCont")); 17020b57cec5SDimitry Andric 17030b57cec5SDimitry Andric if (packet.GetBytesLeft() == 0) { 17049dba64beSDimitry Andric LLDB_LOGF(log, 17059dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s missing action from " 17060b57cec5SDimitry Andric "vCont package", 17070b57cec5SDimitry Andric __FUNCTION__); 17080b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Missing action from vCont package"); 17090b57cec5SDimitry Andric } 17100b57cec5SDimitry Andric 171181ad6265SDimitry Andric if (::strcmp(packet.Peek(), ";s") == 0) { 17120b57cec5SDimitry Andric // Move past the ';', then do a simple 's'. 17130b57cec5SDimitry Andric packet.SetFilePos(packet.GetFilePos() + 1); 17140b57cec5SDimitry Andric return Handle_s(packet); 17150b57cec5SDimitry Andric } 17160b57cec5SDimitry Andric 171781ad6265SDimitry Andric std::unordered_map<lldb::pid_t, ResumeActionList> thread_actions; 17180b57cec5SDimitry Andric 17190b57cec5SDimitry Andric while (packet.GetBytesLeft() && *packet.Peek() == ';') { 17200b57cec5SDimitry Andric // Skip the semi-colon. 17210b57cec5SDimitry Andric packet.GetChar(); 17220b57cec5SDimitry Andric 17230b57cec5SDimitry Andric // Build up the thread action. 17240b57cec5SDimitry Andric ResumeAction thread_action; 17250b57cec5SDimitry Andric thread_action.tid = LLDB_INVALID_THREAD_ID; 17260b57cec5SDimitry Andric thread_action.state = eStateInvalid; 17279dba64beSDimitry Andric thread_action.signal = LLDB_INVALID_SIGNAL_NUMBER; 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andric const char action = packet.GetChar(); 17300b57cec5SDimitry Andric switch (action) { 17310b57cec5SDimitry Andric case 'C': 17320b57cec5SDimitry Andric thread_action.signal = packet.GetHexMaxU32(false, 0); 17330b57cec5SDimitry Andric if (thread_action.signal == 0) 17340b57cec5SDimitry Andric return SendIllFormedResponse( 17350b57cec5SDimitry Andric packet, "Could not parse signal in vCont packet C action"); 17360b57cec5SDimitry Andric LLVM_FALLTHROUGH; 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric case 'c': 17390b57cec5SDimitry Andric // Continue 17400b57cec5SDimitry Andric thread_action.state = eStateRunning; 17410b57cec5SDimitry Andric break; 17420b57cec5SDimitry Andric 17430b57cec5SDimitry Andric case 'S': 17440b57cec5SDimitry Andric thread_action.signal = packet.GetHexMaxU32(false, 0); 17450b57cec5SDimitry Andric if (thread_action.signal == 0) 17460b57cec5SDimitry Andric return SendIllFormedResponse( 17470b57cec5SDimitry Andric packet, "Could not parse signal in vCont packet S action"); 17480b57cec5SDimitry Andric LLVM_FALLTHROUGH; 17490b57cec5SDimitry Andric 17500b57cec5SDimitry Andric case 's': 17510b57cec5SDimitry Andric // Step 17520b57cec5SDimitry Andric thread_action.state = eStateStepping; 17530b57cec5SDimitry Andric break; 17540b57cec5SDimitry Andric 175581ad6265SDimitry Andric case 't': 175681ad6265SDimitry Andric // Stop 175781ad6265SDimitry Andric thread_action.state = eStateSuspended; 175881ad6265SDimitry Andric break; 175981ad6265SDimitry Andric 17600b57cec5SDimitry Andric default: 17610b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Unsupported vCont action"); 17620b57cec5SDimitry Andric break; 17630b57cec5SDimitry Andric } 17640b57cec5SDimitry Andric 176581ad6265SDimitry Andric lldb::pid_t pid = StringExtractorGDBRemote::AllProcesses; 176681ad6265SDimitry Andric lldb::tid_t tid = StringExtractorGDBRemote::AllThreads; 176781ad6265SDimitry Andric 17680b57cec5SDimitry Andric // Parse out optional :{thread-id} value. 17690b57cec5SDimitry Andric if (packet.GetBytesLeft() && (*packet.Peek() == ':')) { 17700b57cec5SDimitry Andric // Consume the separator. 17710b57cec5SDimitry Andric packet.GetChar(); 17720b57cec5SDimitry Andric 177381ad6265SDimitry Andric auto pid_tid = packet.GetPidTid(StringExtractorGDBRemote::AllProcesses); 177481ad6265SDimitry Andric if (!pid_tid) 177581ad6265SDimitry Andric return SendIllFormedResponse(packet, "Malformed thread-id"); 1776fe6060f1SDimitry Andric 177781ad6265SDimitry Andric pid = pid_tid->first; 177881ad6265SDimitry Andric tid = pid_tid->second; 17790b57cec5SDimitry Andric } 17800b57cec5SDimitry Andric 1781fcaf7f86SDimitry Andric if (thread_action.state == eStateSuspended && 1782fcaf7f86SDimitry Andric tid != StringExtractorGDBRemote::AllThreads) { 1783fcaf7f86SDimitry Andric return SendIllFormedResponse( 1784fcaf7f86SDimitry Andric packet, "'t' action not supported for individual threads"); 1785fcaf7f86SDimitry Andric } 1786fcaf7f86SDimitry Andric 178781ad6265SDimitry Andric if (pid == StringExtractorGDBRemote::AllProcesses) { 178881ad6265SDimitry Andric if (m_debugged_processes.size() > 1) 178981ad6265SDimitry Andric return SendIllFormedResponse( 179081ad6265SDimitry Andric packet, "Resuming multiple processes not supported yet"); 179181ad6265SDimitry Andric if (!m_continue_process) { 179281ad6265SDimitry Andric LLDB_LOG(log, "no debugged process"); 179381ad6265SDimitry Andric return SendErrorResponse(0x36); 179481ad6265SDimitry Andric } 179581ad6265SDimitry Andric pid = m_continue_process->GetID(); 17960b57cec5SDimitry Andric } 17970b57cec5SDimitry Andric 179881ad6265SDimitry Andric if (tid == StringExtractorGDBRemote::AllThreads) 179981ad6265SDimitry Andric tid = LLDB_INVALID_THREAD_ID; 180081ad6265SDimitry Andric 180181ad6265SDimitry Andric thread_action.tid = tid; 180281ad6265SDimitry Andric 180381ad6265SDimitry Andric thread_actions[pid].Append(thread_action); 180481ad6265SDimitry Andric } 180581ad6265SDimitry Andric 180681ad6265SDimitry Andric assert(thread_actions.size() >= 1); 180781ad6265SDimitry Andric if (thread_actions.size() > 1) 180881ad6265SDimitry Andric return SendIllFormedResponse( 180981ad6265SDimitry Andric packet, "Resuming multiple processes not supported yet"); 181081ad6265SDimitry Andric 181181ad6265SDimitry Andric for (std::pair<lldb::pid_t, ResumeActionList> x : thread_actions) { 181281ad6265SDimitry Andric auto process_it = m_debugged_processes.find(x.first); 181381ad6265SDimitry Andric if (process_it == m_debugged_processes.end()) { 181481ad6265SDimitry Andric LLDB_LOG(log, "vCont failed for process {0}: process not debugged", 181581ad6265SDimitry Andric x.first); 18160b57cec5SDimitry Andric return SendErrorResponse(GDBRemoteServerError::eErrorResume); 18170b57cec5SDimitry Andric } 18180b57cec5SDimitry Andric 1819fcaf7f86SDimitry Andric // There are four possible scenarios here. These are: 1820fcaf7f86SDimitry Andric // 1. vCont on a stopped process that resumes at least one thread. 1821fcaf7f86SDimitry Andric // In this case, we call Resume(). 1822fcaf7f86SDimitry Andric // 2. vCont on a stopped process that leaves all threads suspended. 1823fcaf7f86SDimitry Andric // A no-op. 1824fcaf7f86SDimitry Andric // 3. vCont on a running process that requests suspending all 1825fcaf7f86SDimitry Andric // running threads. In this case, we call Interrupt(). 1826fcaf7f86SDimitry Andric // 4. vCont on a running process that requests suspending a subset 1827fcaf7f86SDimitry Andric // of running threads or resuming a subset of suspended threads. 1828fcaf7f86SDimitry Andric // Since we do not support full nonstop mode, this is unsupported 1829fcaf7f86SDimitry Andric // and we return an error. 1830fcaf7f86SDimitry Andric 1831fcaf7f86SDimitry Andric assert(process_it->second.process_up); 1832fcaf7f86SDimitry Andric if (ResumeActionListStopsAllThreads(x.second)) { 1833fcaf7f86SDimitry Andric if (process_it->second.process_up->IsRunning()) { 1834fcaf7f86SDimitry Andric assert(m_non_stop); 1835fcaf7f86SDimitry Andric 1836fcaf7f86SDimitry Andric Status error = process_it->second.process_up->Interrupt(); 183781ad6265SDimitry Andric if (error.Fail()) { 1838fcaf7f86SDimitry Andric LLDB_LOG(log, "vCont failed to halt process {0}: {1}", x.first, 1839fcaf7f86SDimitry Andric error); 184081ad6265SDimitry Andric return SendErrorResponse(GDBRemoteServerError::eErrorResume); 184181ad6265SDimitry Andric } 184281ad6265SDimitry Andric 1843fcaf7f86SDimitry Andric LLDB_LOG(log, "halted process {0}", x.first); 1844fcaf7f86SDimitry Andric 1845fcaf7f86SDimitry Andric // hack to avoid enabling stdio forwarding after stop 1846fcaf7f86SDimitry Andric // TODO: remove this when we improve stdio forwarding for nonstop 1847fcaf7f86SDimitry Andric assert(thread_actions.size() == 1); 1848fcaf7f86SDimitry Andric return SendOKResponse(); 1849fcaf7f86SDimitry Andric } 1850fcaf7f86SDimitry Andric } else { 1851fcaf7f86SDimitry Andric PacketResult resume_res = 1852fcaf7f86SDimitry Andric ResumeProcess(*process_it->second.process_up, x.second); 1853fcaf7f86SDimitry Andric if (resume_res != PacketResult::Success) 1854fcaf7f86SDimitry Andric return resume_res; 1855fcaf7f86SDimitry Andric } 185681ad6265SDimitry Andric } 185781ad6265SDimitry Andric 185881ad6265SDimitry Andric return SendContinueSuccessResponse(); 18590b57cec5SDimitry Andric } 18600b57cec5SDimitry Andric 18610b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) { 186281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 18630b57cec5SDimitry Andric LLDB_LOG(log, "setting current thread id to {0}", tid); 18640b57cec5SDimitry Andric 18650b57cec5SDimitry Andric m_current_tid = tid; 1866fe6060f1SDimitry Andric if (m_current_process) 1867fe6060f1SDimitry Andric m_current_process->SetCurrentThreadID(m_current_tid); 18680b57cec5SDimitry Andric } 18690b57cec5SDimitry Andric 18700b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) { 187181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 18720b57cec5SDimitry Andric LLDB_LOG(log, "setting continue thread id to {0}", tid); 18730b57cec5SDimitry Andric 18740b57cec5SDimitry Andric m_continue_tid = tid; 18750b57cec5SDimitry Andric } 18760b57cec5SDimitry Andric 18770b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 18780b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_stop_reason( 18790b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 18800b57cec5SDimitry Andric // Handle the $? gdbremote command. 18810b57cec5SDimitry Andric 188281ad6265SDimitry Andric if (m_non_stop) { 188381ad6265SDimitry Andric // Clear the notification queue first, except for pending exit 188481ad6265SDimitry Andric // notifications. 188581ad6265SDimitry Andric llvm::erase_if(m_stop_notification_queue, [](const std::string &x) { 188681ad6265SDimitry Andric return x.front() != 'W' && x.front() != 'X'; 188781ad6265SDimitry Andric }); 188881ad6265SDimitry Andric 188981ad6265SDimitry Andric if (m_current_process) { 189081ad6265SDimitry Andric // Queue stop reply packets for all active threads. Start with 189181ad6265SDimitry Andric // the current thread (for clients that don't actually support multiple 189281ad6265SDimitry Andric // stop reasons). 189381ad6265SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); 1894fcaf7f86SDimitry Andric if (thread) { 1895fcaf7f86SDimitry Andric StreamString stop_reply = PrepareStopReplyPacketForThread(*thread); 1896fcaf7f86SDimitry Andric if (!stop_reply.Empty()) 1897fcaf7f86SDimitry Andric m_stop_notification_queue.push_back(stop_reply.GetString().str()); 1898fcaf7f86SDimitry Andric } 189981ad6265SDimitry Andric EnqueueStopReplyPackets(thread ? thread->GetID() 190081ad6265SDimitry Andric : LLDB_INVALID_THREAD_ID); 190181ad6265SDimitry Andric } 190281ad6265SDimitry Andric 190381ad6265SDimitry Andric // If the notification queue is empty (i.e. everything is running), send OK. 190481ad6265SDimitry Andric if (m_stop_notification_queue.empty()) 190581ad6265SDimitry Andric return SendOKResponse(); 190681ad6265SDimitry Andric 190781ad6265SDimitry Andric // Send the first item from the new notification queue synchronously. 190881ad6265SDimitry Andric return SendPacketNoLock(m_stop_notification_queue.front()); 190981ad6265SDimitry Andric } 191081ad6265SDimitry Andric 19110b57cec5SDimitry Andric // If no process, indicate error 1912fe6060f1SDimitry Andric if (!m_current_process) 19130b57cec5SDimitry Andric return SendErrorResponse(02); 19140b57cec5SDimitry Andric 191581ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 191681ad6265SDimitry Andric m_current_process->GetState(), 191781ad6265SDimitry Andric /*force_synchronous=*/true); 19180b57cec5SDimitry Andric } 19190b57cec5SDimitry Andric 19200b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 19210b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendStopReasonForState( 192281ad6265SDimitry Andric NativeProcessProtocol &process, lldb::StateType process_state, 192381ad6265SDimitry Andric bool force_synchronous) { 192481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 19250b57cec5SDimitry Andric 1926fcaf7f86SDimitry Andric if (m_disabling_non_stop) { 1927fcaf7f86SDimitry Andric // Check if we are waiting for any more processes to stop. If we are, 1928fcaf7f86SDimitry Andric // do not send the OK response yet. 1929fcaf7f86SDimitry Andric for (const auto &it : m_debugged_processes) { 1930fcaf7f86SDimitry Andric if (it.second.process_up->IsRunning()) 1931fcaf7f86SDimitry Andric return PacketResult::Success; 1932fcaf7f86SDimitry Andric } 1933fcaf7f86SDimitry Andric 1934fcaf7f86SDimitry Andric // If all expected processes were stopped after a QNonStop:0 request, 1935fcaf7f86SDimitry Andric // send the OK response. 1936fcaf7f86SDimitry Andric m_disabling_non_stop = false; 1937fcaf7f86SDimitry Andric return SendOKResponse(); 1938fcaf7f86SDimitry Andric } 1939fcaf7f86SDimitry Andric 19400b57cec5SDimitry Andric switch (process_state) { 19410b57cec5SDimitry Andric case eStateAttaching: 19420b57cec5SDimitry Andric case eStateLaunching: 19430b57cec5SDimitry Andric case eStateRunning: 19440b57cec5SDimitry Andric case eStateStepping: 19450b57cec5SDimitry Andric case eStateDetached: 19460b57cec5SDimitry Andric // NOTE: gdb protocol doc looks like it should return $OK 19470b57cec5SDimitry Andric // when everything is running (i.e. no stopped result). 19480b57cec5SDimitry Andric return PacketResult::Success; // Ignore 19490b57cec5SDimitry Andric 19500b57cec5SDimitry Andric case eStateSuspended: 19510b57cec5SDimitry Andric case eStateStopped: 19520b57cec5SDimitry Andric case eStateCrashed: { 195381ad6265SDimitry Andric lldb::tid_t tid = process.GetCurrentThreadID(); 19540b57cec5SDimitry Andric // Make sure we set the current thread so g and p packets return the data 19550b57cec5SDimitry Andric // the gdb will expect. 19560b57cec5SDimitry Andric SetCurrentThreadID(tid); 195781ad6265SDimitry Andric return SendStopReplyPacketForThread(process, tid, force_synchronous); 19580b57cec5SDimitry Andric } 19590b57cec5SDimitry Andric 19600b57cec5SDimitry Andric case eStateInvalid: 19610b57cec5SDimitry Andric case eStateUnloaded: 19620b57cec5SDimitry Andric case eStateExited: 196381ad6265SDimitry Andric return SendWResponse(&process); 19640b57cec5SDimitry Andric 19650b57cec5SDimitry Andric default: 19660b57cec5SDimitry Andric LLDB_LOG(log, "pid {0}, current state reporting not handled: {1}", 196781ad6265SDimitry Andric process.GetID(), process_state); 19680b57cec5SDimitry Andric break; 19690b57cec5SDimitry Andric } 19700b57cec5SDimitry Andric 19710b57cec5SDimitry Andric return SendErrorResponse(0); 19720b57cec5SDimitry Andric } 19730b57cec5SDimitry Andric 19740b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 19750b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( 19760b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 19770b57cec5SDimitry Andric // Fail if we don't have a current process. 1978fe6060f1SDimitry Andric if (!m_current_process || 1979fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 19800b57cec5SDimitry Andric return SendErrorResponse(68); 19810b57cec5SDimitry Andric 19820b57cec5SDimitry Andric // Ensure we have a thread. 1983fe6060f1SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0); 19840b57cec5SDimitry Andric if (!thread) 19850b57cec5SDimitry Andric return SendErrorResponse(69); 19860b57cec5SDimitry Andric 19870b57cec5SDimitry Andric // Get the register context for the first thread. 19880b57cec5SDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 19890b57cec5SDimitry Andric 19900b57cec5SDimitry Andric // Parse out the register number from the request. 19910b57cec5SDimitry Andric packet.SetFilePos(strlen("qRegisterInfo")); 19920b57cec5SDimitry Andric const uint32_t reg_index = 19930b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 19940b57cec5SDimitry Andric if (reg_index == std::numeric_limits<uint32_t>::max()) 19950b57cec5SDimitry Andric return SendErrorResponse(69); 19960b57cec5SDimitry Andric 19970b57cec5SDimitry Andric // Return the end of registers response if we've iterated one past the end of 19980b57cec5SDimitry Andric // the register set. 19990b57cec5SDimitry Andric if (reg_index >= reg_context.GetUserRegisterCount()) 20000b57cec5SDimitry Andric return SendErrorResponse(69); 20010b57cec5SDimitry Andric 20020b57cec5SDimitry Andric const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); 20030b57cec5SDimitry Andric if (!reg_info) 20040b57cec5SDimitry Andric return SendErrorResponse(69); 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andric // Build the reginfos response. 20070b57cec5SDimitry Andric StreamGDBRemote response; 20080b57cec5SDimitry Andric 20090b57cec5SDimitry Andric response.PutCString("name:"); 20100b57cec5SDimitry Andric response.PutCString(reg_info->name); 20110b57cec5SDimitry Andric response.PutChar(';'); 20120b57cec5SDimitry Andric 20130b57cec5SDimitry Andric if (reg_info->alt_name && reg_info->alt_name[0]) { 20140b57cec5SDimitry Andric response.PutCString("alt-name:"); 20150b57cec5SDimitry Andric response.PutCString(reg_info->alt_name); 20160b57cec5SDimitry Andric response.PutChar(';'); 20170b57cec5SDimitry Andric } 20180b57cec5SDimitry Andric 2019e8d8bef9SDimitry Andric response.Printf("bitsize:%" PRIu32 ";", reg_info->byte_size * 8); 2020e8d8bef9SDimitry Andric 2021e8d8bef9SDimitry Andric if (!reg_context.RegisterOffsetIsDynamic()) 2022e8d8bef9SDimitry Andric response.Printf("offset:%" PRIu32 ";", reg_info->byte_offset); 20230b57cec5SDimitry Andric 20245ffd83dbSDimitry Andric llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info); 20255ffd83dbSDimitry Andric if (!encoding.empty()) 20265ffd83dbSDimitry Andric response << "encoding:" << encoding << ';'; 20270b57cec5SDimitry Andric 20285ffd83dbSDimitry Andric llvm::StringRef format = GetFormatNameOrEmpty(*reg_info); 20295ffd83dbSDimitry Andric if (!format.empty()) 20305ffd83dbSDimitry Andric response << "format:" << format << ';'; 20310b57cec5SDimitry Andric 20320b57cec5SDimitry Andric const char *const register_set_name = 20330b57cec5SDimitry Andric reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); 20345ffd83dbSDimitry Andric if (register_set_name) 20355ffd83dbSDimitry Andric response << "set:" << register_set_name << ';'; 20360b57cec5SDimitry Andric 20370b57cec5SDimitry Andric if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != 20380b57cec5SDimitry Andric LLDB_INVALID_REGNUM) 20390b57cec5SDimitry Andric response.Printf("ehframe:%" PRIu32 ";", 20400b57cec5SDimitry Andric reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); 20410b57cec5SDimitry Andric 20420b57cec5SDimitry Andric if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM) 20430b57cec5SDimitry Andric response.Printf("dwarf:%" PRIu32 ";", 20440b57cec5SDimitry Andric reg_info->kinds[RegisterKind::eRegisterKindDWARF]); 20450b57cec5SDimitry Andric 20465ffd83dbSDimitry Andric llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info); 20475ffd83dbSDimitry Andric if (!kind_generic.empty()) 20485ffd83dbSDimitry Andric response << "generic:" << kind_generic << ';'; 20490b57cec5SDimitry Andric 20500b57cec5SDimitry Andric if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { 20510b57cec5SDimitry Andric response.PutCString("container-regs:"); 20525ffd83dbSDimitry Andric CollectRegNums(reg_info->value_regs, response, true); 20530b57cec5SDimitry Andric response.PutChar(';'); 20540b57cec5SDimitry Andric } 20550b57cec5SDimitry Andric 20560b57cec5SDimitry Andric if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { 20570b57cec5SDimitry Andric response.PutCString("invalidate-regs:"); 20585ffd83dbSDimitry Andric CollectRegNums(reg_info->invalidate_regs, response, true); 20590b57cec5SDimitry Andric response.PutChar(';'); 20600b57cec5SDimitry Andric } 20610b57cec5SDimitry Andric 20620b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 20630b57cec5SDimitry Andric } 20640b57cec5SDimitry Andric 206581ad6265SDimitry Andric void GDBRemoteCommunicationServerLLGS::AddProcessThreads( 206681ad6265SDimitry Andric StreamGDBRemote &response, NativeProcessProtocol &process, bool &had_any) { 206781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 206881ad6265SDimitry Andric 206981ad6265SDimitry Andric lldb::pid_t pid = process.GetID(); 207081ad6265SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 207181ad6265SDimitry Andric return; 207281ad6265SDimitry Andric 207381ad6265SDimitry Andric LLDB_LOG(log, "iterating over threads of process {0}", process.GetID()); 207481ad6265SDimitry Andric for (NativeThreadProtocol &thread : process.Threads()) { 207581ad6265SDimitry Andric LLDB_LOG(log, "iterated thread tid={0}", thread.GetID()); 207681ad6265SDimitry Andric response.PutChar(had_any ? ',' : 'm'); 207781ad6265SDimitry Andric AppendThreadIDToResponse(response, pid, thread.GetID()); 207881ad6265SDimitry Andric had_any = true; 207981ad6265SDimitry Andric } 208081ad6265SDimitry Andric } 208181ad6265SDimitry Andric 20820b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 20830b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo( 20840b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 208581ad6265SDimitry Andric assert(m_debugged_processes.size() == 1 || 208681ad6265SDimitry Andric bool(m_extensions_supported & 208781ad6265SDimitry Andric NativeProcessProtocol::Extension::multiprocess)); 20880b57cec5SDimitry Andric 208981ad6265SDimitry Andric bool had_any = false; 20900b57cec5SDimitry Andric StreamGDBRemote response; 20910b57cec5SDimitry Andric 209281ad6265SDimitry Andric for (auto &pid_ptr : m_debugged_processes) 2093fcaf7f86SDimitry Andric AddProcessThreads(response, *pid_ptr.second.process_up, had_any); 20940b57cec5SDimitry Andric 209581ad6265SDimitry Andric if (!had_any) 209681ad6265SDimitry Andric return SendOKResponse(); 20970b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 20980b57cec5SDimitry Andric } 20990b57cec5SDimitry Andric 21000b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 21010b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo( 21020b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 21030b57cec5SDimitry Andric // FIXME for now we return the full thread list in the initial packet and 21040b57cec5SDimitry Andric // always do nothing here. 21050b57cec5SDimitry Andric return SendPacketNoLock("l"); 21060b57cec5SDimitry Andric } 21070b57cec5SDimitry Andric 21080b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 21090b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) { 211081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 21110b57cec5SDimitry Andric 21120b57cec5SDimitry Andric // Move past packet name. 21130b57cec5SDimitry Andric packet.SetFilePos(strlen("g")); 21140b57cec5SDimitry Andric 21150b57cec5SDimitry Andric // Get the thread to use. 21160b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 21170b57cec5SDimitry Andric if (!thread) { 21180b57cec5SDimitry Andric LLDB_LOG(log, "failed, no thread available"); 21190b57cec5SDimitry Andric return SendErrorResponse(0x15); 21200b57cec5SDimitry Andric } 21210b57cec5SDimitry Andric 21220b57cec5SDimitry Andric // Get the thread's register context. 21230b57cec5SDimitry Andric NativeRegisterContext ®_ctx = thread->GetRegisterContext(); 21240b57cec5SDimitry Andric 21250b57cec5SDimitry Andric std::vector<uint8_t> regs_buffer; 21260b57cec5SDimitry Andric for (uint32_t reg_num = 0; reg_num < reg_ctx.GetUserRegisterCount(); 21270b57cec5SDimitry Andric ++reg_num) { 21280b57cec5SDimitry Andric const RegisterInfo *reg_info = reg_ctx.GetRegisterInfoAtIndex(reg_num); 21290b57cec5SDimitry Andric 21300b57cec5SDimitry Andric if (reg_info == nullptr) { 21310b57cec5SDimitry Andric LLDB_LOG(log, "failed to get register info for register index {0}", 21320b57cec5SDimitry Andric reg_num); 21330b57cec5SDimitry Andric return SendErrorResponse(0x15); 21340b57cec5SDimitry Andric } 21350b57cec5SDimitry Andric 21360b57cec5SDimitry Andric if (reg_info->value_regs != nullptr) 21370b57cec5SDimitry Andric continue; // skip registers that are contained in other registers 21380b57cec5SDimitry Andric 21390b57cec5SDimitry Andric RegisterValue reg_value; 21400b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(reg_info, reg_value); 21410b57cec5SDimitry Andric if (error.Fail()) { 21420b57cec5SDimitry Andric LLDB_LOG(log, "failed to read register at index {0}", reg_num); 21430b57cec5SDimitry Andric return SendErrorResponse(0x15); 21440b57cec5SDimitry Andric } 21450b57cec5SDimitry Andric 21460b57cec5SDimitry Andric if (reg_info->byte_offset + reg_info->byte_size >= regs_buffer.size()) 21470b57cec5SDimitry Andric // Resize the buffer to guarantee it can store the register offsetted 21480b57cec5SDimitry Andric // data. 21490b57cec5SDimitry Andric regs_buffer.resize(reg_info->byte_offset + reg_info->byte_size); 21500b57cec5SDimitry Andric 21510b57cec5SDimitry Andric // Copy the register offsetted data to the buffer. 21520b57cec5SDimitry Andric memcpy(regs_buffer.data() + reg_info->byte_offset, reg_value.GetBytes(), 21530b57cec5SDimitry Andric reg_info->byte_size); 21540b57cec5SDimitry Andric } 21550b57cec5SDimitry Andric 21560b57cec5SDimitry Andric // Write the response. 21570b57cec5SDimitry Andric StreamGDBRemote response; 21580b57cec5SDimitry Andric response.PutBytesAsRawHex8(regs_buffer.data(), regs_buffer.size()); 21590b57cec5SDimitry Andric 21600b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 21610b57cec5SDimitry Andric } 21620b57cec5SDimitry Andric 21630b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 21640b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { 216581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 21660b57cec5SDimitry Andric 21670b57cec5SDimitry Andric // Parse out the register number from the request. 21680b57cec5SDimitry Andric packet.SetFilePos(strlen("p")); 21690b57cec5SDimitry Andric const uint32_t reg_index = 21700b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 21710b57cec5SDimitry Andric if (reg_index == std::numeric_limits<uint32_t>::max()) { 21729dba64beSDimitry Andric LLDB_LOGF(log, 21739dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, could not " 21740b57cec5SDimitry Andric "parse register number from request \"%s\"", 21759dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 21760b57cec5SDimitry Andric return SendErrorResponse(0x15); 21770b57cec5SDimitry Andric } 21780b57cec5SDimitry Andric 21790b57cec5SDimitry Andric // Get the thread to use. 21800b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 21810b57cec5SDimitry Andric if (!thread) { 21820b57cec5SDimitry Andric LLDB_LOG(log, "failed, no thread available"); 21830b57cec5SDimitry Andric return SendErrorResponse(0x15); 21840b57cec5SDimitry Andric } 21850b57cec5SDimitry Andric 21860b57cec5SDimitry Andric // Get the thread's register context. 21870b57cec5SDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 21880b57cec5SDimitry Andric 21890b57cec5SDimitry Andric // Return the end of registers response if we've iterated one past the end of 21900b57cec5SDimitry Andric // the register set. 21910b57cec5SDimitry Andric if (reg_index >= reg_context.GetUserRegisterCount()) { 21929dba64beSDimitry Andric LLDB_LOGF(log, 21939dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, requested " 21940b57cec5SDimitry Andric "register %" PRIu32 " beyond register count %" PRIu32, 21959dba64beSDimitry Andric __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); 21960b57cec5SDimitry Andric return SendErrorResponse(0x15); 21970b57cec5SDimitry Andric } 21980b57cec5SDimitry Andric 21990b57cec5SDimitry Andric const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); 22000b57cec5SDimitry Andric if (!reg_info) { 22019dba64beSDimitry Andric LLDB_LOGF(log, 22029dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, requested " 22030b57cec5SDimitry Andric "register %" PRIu32 " returned NULL", 22040b57cec5SDimitry Andric __FUNCTION__, reg_index); 22050b57cec5SDimitry Andric return SendErrorResponse(0x15); 22060b57cec5SDimitry Andric } 22070b57cec5SDimitry Andric 22080b57cec5SDimitry Andric // Build the reginfos response. 22090b57cec5SDimitry Andric StreamGDBRemote response; 22100b57cec5SDimitry Andric 22110b57cec5SDimitry Andric // Retrieve the value 22120b57cec5SDimitry Andric RegisterValue reg_value; 22130b57cec5SDimitry Andric Status error = reg_context.ReadRegister(reg_info, reg_value); 22140b57cec5SDimitry Andric if (error.Fail()) { 22159dba64beSDimitry Andric LLDB_LOGF(log, 22169dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, read of " 22170b57cec5SDimitry Andric "requested register %" PRIu32 " (%s) failed: %s", 22180b57cec5SDimitry Andric __FUNCTION__, reg_index, reg_info->name, error.AsCString()); 22190b57cec5SDimitry Andric return SendErrorResponse(0x15); 22200b57cec5SDimitry Andric } 22210b57cec5SDimitry Andric 22220b57cec5SDimitry Andric const uint8_t *const data = 2223480093f4SDimitry Andric static_cast<const uint8_t *>(reg_value.GetBytes()); 22240b57cec5SDimitry Andric if (!data) { 22259dba64beSDimitry Andric LLDB_LOGF(log, 22269dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to get data " 22270b57cec5SDimitry Andric "bytes from requested register %" PRIu32, 22280b57cec5SDimitry Andric __FUNCTION__, reg_index); 22290b57cec5SDimitry Andric return SendErrorResponse(0x15); 22300b57cec5SDimitry Andric } 22310b57cec5SDimitry Andric 22320b57cec5SDimitry Andric // FIXME flip as needed to get data in big/little endian format for this host. 22330b57cec5SDimitry Andric for (uint32_t i = 0; i < reg_value.GetByteSize(); ++i) 22340b57cec5SDimitry Andric response.PutHex8(data[i]); 22350b57cec5SDimitry Andric 22360b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 22370b57cec5SDimitry Andric } 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 22400b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { 224181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 22420b57cec5SDimitry Andric 22430b57cec5SDimitry Andric // Ensure there is more content. 22440b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 22450b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Empty P packet"); 22460b57cec5SDimitry Andric 22470b57cec5SDimitry Andric // Parse out the register number from the request. 22480b57cec5SDimitry Andric packet.SetFilePos(strlen("P")); 22490b57cec5SDimitry Andric const uint32_t reg_index = 22500b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 22510b57cec5SDimitry Andric if (reg_index == std::numeric_limits<uint32_t>::max()) { 22529dba64beSDimitry Andric LLDB_LOGF(log, 22539dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, could not " 22540b57cec5SDimitry Andric "parse register number from request \"%s\"", 22559dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 22560b57cec5SDimitry Andric return SendErrorResponse(0x29); 22570b57cec5SDimitry Andric } 22580b57cec5SDimitry Andric 22590b57cec5SDimitry Andric // Note debugserver would send an E30 here. 22600b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != '=')) 22610b57cec5SDimitry Andric return SendIllFormedResponse( 22620b57cec5SDimitry Andric packet, "P packet missing '=' char after register number"); 22630b57cec5SDimitry Andric 22640b57cec5SDimitry Andric // Parse out the value. 22655ffd83dbSDimitry Andric uint8_t reg_bytes[RegisterValue::kMaxRegisterByteSize]; 22660b57cec5SDimitry Andric size_t reg_size = packet.GetHexBytesAvail(reg_bytes); 22670b57cec5SDimitry Andric 22680b57cec5SDimitry Andric // Get the thread to use. 22690b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 22700b57cec5SDimitry Andric if (!thread) { 22719dba64beSDimitry Andric LLDB_LOGF(log, 22729dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no thread " 22730b57cec5SDimitry Andric "available (thread index 0)", 22740b57cec5SDimitry Andric __FUNCTION__); 22750b57cec5SDimitry Andric return SendErrorResponse(0x28); 22760b57cec5SDimitry Andric } 22770b57cec5SDimitry Andric 22780b57cec5SDimitry Andric // Get the thread's register context. 22790b57cec5SDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 22800b57cec5SDimitry Andric const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); 22810b57cec5SDimitry Andric if (!reg_info) { 22829dba64beSDimitry Andric LLDB_LOGF(log, 22839dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, requested " 22840b57cec5SDimitry Andric "register %" PRIu32 " returned NULL", 22850b57cec5SDimitry Andric __FUNCTION__, reg_index); 22860b57cec5SDimitry Andric return SendErrorResponse(0x48); 22870b57cec5SDimitry Andric } 22880b57cec5SDimitry Andric 22890b57cec5SDimitry Andric // Return the end of registers response if we've iterated one past the end of 22900b57cec5SDimitry Andric // the register set. 22910b57cec5SDimitry Andric if (reg_index >= reg_context.GetUserRegisterCount()) { 22929dba64beSDimitry Andric LLDB_LOGF(log, 22939dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, requested " 22940b57cec5SDimitry Andric "register %" PRIu32 " beyond register count %" PRIu32, 22950b57cec5SDimitry Andric __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); 22960b57cec5SDimitry Andric return SendErrorResponse(0x47); 22970b57cec5SDimitry Andric } 22980b57cec5SDimitry Andric 2299349cc55cSDimitry Andric if (reg_size != reg_info->byte_size) 23000b57cec5SDimitry Andric return SendIllFormedResponse(packet, "P packet register size is incorrect"); 23010b57cec5SDimitry Andric 23020b57cec5SDimitry Andric // Build the reginfos response. 23030b57cec5SDimitry Andric StreamGDBRemote response; 23040b57cec5SDimitry Andric 2305fe6060f1SDimitry Andric RegisterValue reg_value(makeArrayRef(reg_bytes, reg_size), 2306fe6060f1SDimitry Andric m_current_process->GetArchitecture().GetByteOrder()); 23070b57cec5SDimitry Andric Status error = reg_context.WriteRegister(reg_info, reg_value); 23080b57cec5SDimitry Andric if (error.Fail()) { 23099dba64beSDimitry Andric LLDB_LOGF(log, 23109dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, write of " 23110b57cec5SDimitry Andric "requested register %" PRIu32 " (%s) failed: %s", 23120b57cec5SDimitry Andric __FUNCTION__, reg_index, reg_info->name, error.AsCString()); 23130b57cec5SDimitry Andric return SendErrorResponse(0x32); 23140b57cec5SDimitry Andric } 23150b57cec5SDimitry Andric 23160b57cec5SDimitry Andric return SendOKResponse(); 23170b57cec5SDimitry Andric } 23180b57cec5SDimitry Andric 23190b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 23200b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { 232181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 23220b57cec5SDimitry Andric 23230b57cec5SDimitry Andric // Parse out which variant of $H is requested. 23240b57cec5SDimitry Andric packet.SetFilePos(strlen("H")); 23250b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) { 23269dba64beSDimitry Andric LLDB_LOGF(log, 23279dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, H command " 23280b57cec5SDimitry Andric "missing {g,c} variant", 23290b57cec5SDimitry Andric __FUNCTION__); 23300b57cec5SDimitry Andric return SendIllFormedResponse(packet, "H command missing {g,c} variant"); 23310b57cec5SDimitry Andric } 23320b57cec5SDimitry Andric 23330b57cec5SDimitry Andric const char h_variant = packet.GetChar(); 2334fe6060f1SDimitry Andric NativeProcessProtocol *default_process; 23350b57cec5SDimitry Andric switch (h_variant) { 23360b57cec5SDimitry Andric case 'g': 2337fe6060f1SDimitry Andric default_process = m_current_process; 23380b57cec5SDimitry Andric break; 23390b57cec5SDimitry Andric 23400b57cec5SDimitry Andric case 'c': 2341fe6060f1SDimitry Andric default_process = m_continue_process; 23420b57cec5SDimitry Andric break; 23430b57cec5SDimitry Andric 23440b57cec5SDimitry Andric default: 23459dba64beSDimitry Andric LLDB_LOGF( 23469dba64beSDimitry Andric log, 23470b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", 23480b57cec5SDimitry Andric __FUNCTION__, h_variant); 23490b57cec5SDimitry Andric return SendIllFormedResponse(packet, 23500b57cec5SDimitry Andric "H variant unsupported, should be c or g"); 23510b57cec5SDimitry Andric } 23520b57cec5SDimitry Andric 23530b57cec5SDimitry Andric // Parse out the thread number. 2354fe6060f1SDimitry Andric auto pid_tid = packet.GetPidTid(default_process ? default_process->GetID() 2355fe6060f1SDimitry Andric : LLDB_INVALID_PROCESS_ID); 2356fe6060f1SDimitry Andric if (!pid_tid) 2357fe6060f1SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 2358fe6060f1SDimitry Andric inconvertibleErrorCode(), "Malformed thread-id")); 2359fe6060f1SDimitry Andric 2360fe6060f1SDimitry Andric lldb::pid_t pid = pid_tid->first; 2361fe6060f1SDimitry Andric lldb::tid_t tid = pid_tid->second; 2362fe6060f1SDimitry Andric 2363fe6060f1SDimitry Andric if (pid == StringExtractorGDBRemote::AllProcesses) 2364fe6060f1SDimitry Andric return SendUnimplementedResponse("Selecting all processes not supported"); 2365fe6060f1SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 2366fe6060f1SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 2367fe6060f1SDimitry Andric inconvertibleErrorCode(), "No current process and no PID provided")); 2368fe6060f1SDimitry Andric 2369fe6060f1SDimitry Andric // Check the process ID and find respective process instance. 2370fe6060f1SDimitry Andric auto new_process_it = m_debugged_processes.find(pid); 2371fe6060f1SDimitry Andric if (new_process_it == m_debugged_processes.end()) 2372fe6060f1SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 2373fe6060f1SDimitry Andric inconvertibleErrorCode(), 2374fe6060f1SDimitry Andric llvm::formatv("No process with PID {0} debugged", pid))); 23750b57cec5SDimitry Andric 23760b57cec5SDimitry Andric // Ensure we have the given thread when not specifying -1 (all threads) or 0 23770b57cec5SDimitry Andric // (any thread). 23780b57cec5SDimitry Andric if (tid != LLDB_INVALID_THREAD_ID && tid != 0) { 2379fcaf7f86SDimitry Andric NativeThreadProtocol *thread = 2380fcaf7f86SDimitry Andric new_process_it->second.process_up->GetThreadByID(tid); 23810b57cec5SDimitry Andric if (!thread) { 23829dba64beSDimitry Andric LLDB_LOGF(log, 23839dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 23840b57cec5SDimitry Andric " not found", 23850b57cec5SDimitry Andric __FUNCTION__, tid); 23860b57cec5SDimitry Andric return SendErrorResponse(0x15); 23870b57cec5SDimitry Andric } 23880b57cec5SDimitry Andric } 23890b57cec5SDimitry Andric 2390fe6060f1SDimitry Andric // Now switch the given process and thread type. 23910b57cec5SDimitry Andric switch (h_variant) { 23920b57cec5SDimitry Andric case 'g': 2393fcaf7f86SDimitry Andric m_current_process = new_process_it->second.process_up.get(); 23940b57cec5SDimitry Andric SetCurrentThreadID(tid); 23950b57cec5SDimitry Andric break; 23960b57cec5SDimitry Andric 23970b57cec5SDimitry Andric case 'c': 2398fcaf7f86SDimitry Andric m_continue_process = new_process_it->second.process_up.get(); 23990b57cec5SDimitry Andric SetContinueThreadID(tid); 24000b57cec5SDimitry Andric break; 24010b57cec5SDimitry Andric 24020b57cec5SDimitry Andric default: 24030b57cec5SDimitry Andric assert(false && "unsupported $H variant - shouldn't get here"); 24040b57cec5SDimitry Andric return SendIllFormedResponse(packet, 24050b57cec5SDimitry Andric "H variant unsupported, should be c or g"); 24060b57cec5SDimitry Andric } 24070b57cec5SDimitry Andric 24080b57cec5SDimitry Andric return SendOKResponse(); 24090b57cec5SDimitry Andric } 24100b57cec5SDimitry Andric 24110b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 24120b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) { 241381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 24140b57cec5SDimitry Andric 24150b57cec5SDimitry Andric // Fail if we don't have a current process. 2416fe6060f1SDimitry Andric if (!m_current_process || 2417fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 24189dba64beSDimitry Andric LLDB_LOGF( 24199dba64beSDimitry Andric log, 24200b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 24210b57cec5SDimitry Andric __FUNCTION__); 24220b57cec5SDimitry Andric return SendErrorResponse(0x15); 24230b57cec5SDimitry Andric } 24240b57cec5SDimitry Andric 24250b57cec5SDimitry Andric packet.SetFilePos(::strlen("I")); 24260b57cec5SDimitry Andric uint8_t tmp[4096]; 24270b57cec5SDimitry Andric for (;;) { 24280b57cec5SDimitry Andric size_t read = packet.GetHexBytesAvail(tmp); 24290b57cec5SDimitry Andric if (read == 0) { 24300b57cec5SDimitry Andric break; 24310b57cec5SDimitry Andric } 24320b57cec5SDimitry Andric // write directly to stdin *this might block if stdin buffer is full* 24330b57cec5SDimitry Andric // TODO: enqueue this block in circular buffer and send window size to 24340b57cec5SDimitry Andric // remote host 24350b57cec5SDimitry Andric ConnectionStatus status; 24360b57cec5SDimitry Andric Status error; 24370b57cec5SDimitry Andric m_stdio_communication.Write(tmp, read, status, &error); 24380b57cec5SDimitry Andric if (error.Fail()) { 24390b57cec5SDimitry Andric return SendErrorResponse(0x15); 24400b57cec5SDimitry Andric } 24410b57cec5SDimitry Andric } 24420b57cec5SDimitry Andric 24430b57cec5SDimitry Andric return SendOKResponse(); 24440b57cec5SDimitry Andric } 24450b57cec5SDimitry Andric 24460b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 24470b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_interrupt( 24480b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 244981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 24500b57cec5SDimitry Andric 24510b57cec5SDimitry Andric // Fail if we don't have a current process. 2452fe6060f1SDimitry Andric if (!m_current_process || 2453fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 24540b57cec5SDimitry Andric LLDB_LOG(log, "failed, no process available"); 24550b57cec5SDimitry Andric return SendErrorResponse(0x15); 24560b57cec5SDimitry Andric } 24570b57cec5SDimitry Andric 24580b57cec5SDimitry Andric // Interrupt the process. 2459fe6060f1SDimitry Andric Status error = m_current_process->Interrupt(); 24600b57cec5SDimitry Andric if (error.Fail()) { 2461fe6060f1SDimitry Andric LLDB_LOG(log, "failed for process {0}: {1}", m_current_process->GetID(), 24620b57cec5SDimitry Andric error); 24630b57cec5SDimitry Andric return SendErrorResponse(GDBRemoteServerError::eErrorResume); 24640b57cec5SDimitry Andric } 24650b57cec5SDimitry Andric 2466fe6060f1SDimitry Andric LLDB_LOG(log, "stopped process {0}", m_current_process->GetID()); 24670b57cec5SDimitry Andric 24680b57cec5SDimitry Andric // No response required from stop all. 24690b57cec5SDimitry Andric return PacketResult::Success; 24700b57cec5SDimitry Andric } 24710b57cec5SDimitry Andric 24720b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 24730b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_memory_read( 24740b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 247581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 24760b57cec5SDimitry Andric 2477fe6060f1SDimitry Andric if (!m_current_process || 2478fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 24799dba64beSDimitry Andric LLDB_LOGF( 24809dba64beSDimitry Andric log, 24810b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 24820b57cec5SDimitry Andric __FUNCTION__); 24830b57cec5SDimitry Andric return SendErrorResponse(0x15); 24840b57cec5SDimitry Andric } 24850b57cec5SDimitry Andric 24860b57cec5SDimitry Andric // Parse out the memory address. 24870b57cec5SDimitry Andric packet.SetFilePos(strlen("m")); 24880b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 24890b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short m packet"); 24900b57cec5SDimitry Andric 24910b57cec5SDimitry Andric // Read the address. Punting on validation. 24920b57cec5SDimitry Andric // FIXME replace with Hex U64 read with no default value that fails on failed 24930b57cec5SDimitry Andric // read. 24940b57cec5SDimitry Andric const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0); 24950b57cec5SDimitry Andric 24960b57cec5SDimitry Andric // Validate comma. 24970b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) 24980b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Comma sep missing in m packet"); 24990b57cec5SDimitry Andric 25000b57cec5SDimitry Andric // Get # bytes to read. 25010b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 25020b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Length missing in m packet"); 25030b57cec5SDimitry Andric 25040b57cec5SDimitry Andric const uint64_t byte_count = packet.GetHexMaxU64(false, 0); 25050b57cec5SDimitry Andric if (byte_count == 0) { 25069dba64beSDimitry Andric LLDB_LOGF(log, 25079dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s nothing to read: " 25080b57cec5SDimitry Andric "zero-length packet", 25090b57cec5SDimitry Andric __FUNCTION__); 25100b57cec5SDimitry Andric return SendOKResponse(); 25110b57cec5SDimitry Andric } 25120b57cec5SDimitry Andric 25130b57cec5SDimitry Andric // Allocate the response buffer. 25140b57cec5SDimitry Andric std::string buf(byte_count, '\0'); 25150b57cec5SDimitry Andric if (buf.empty()) 25160b57cec5SDimitry Andric return SendErrorResponse(0x78); 25170b57cec5SDimitry Andric 25180b57cec5SDimitry Andric // Retrieve the process memory. 25190b57cec5SDimitry Andric size_t bytes_read = 0; 2520fe6060f1SDimitry Andric Status error = m_current_process->ReadMemoryWithoutTrap( 25210b57cec5SDimitry Andric read_addr, &buf[0], byte_count, bytes_read); 25220b57cec5SDimitry Andric if (error.Fail()) { 25239dba64beSDimitry Andric LLDB_LOGF(log, 25249dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 25250b57cec5SDimitry Andric " mem 0x%" PRIx64 ": failed to read. Error: %s", 2526fe6060f1SDimitry Andric __FUNCTION__, m_current_process->GetID(), read_addr, 25270b57cec5SDimitry Andric error.AsCString()); 25280b57cec5SDimitry Andric return SendErrorResponse(0x08); 25290b57cec5SDimitry Andric } 25300b57cec5SDimitry Andric 25310b57cec5SDimitry Andric if (bytes_read == 0) { 25329dba64beSDimitry Andric LLDB_LOGF(log, 25339dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 25340b57cec5SDimitry Andric " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", 2535fe6060f1SDimitry Andric __FUNCTION__, m_current_process->GetID(), read_addr, byte_count); 25360b57cec5SDimitry Andric return SendErrorResponse(0x08); 25370b57cec5SDimitry Andric } 25380b57cec5SDimitry Andric 25390b57cec5SDimitry Andric StreamGDBRemote response; 25400b57cec5SDimitry Andric packet.SetFilePos(0); 25410b57cec5SDimitry Andric char kind = packet.GetChar('?'); 25420b57cec5SDimitry Andric if (kind == 'x') 25430b57cec5SDimitry Andric response.PutEscapedBytes(buf.data(), byte_count); 25440b57cec5SDimitry Andric else { 25450b57cec5SDimitry Andric assert(kind == 'm'); 25460b57cec5SDimitry Andric for (size_t i = 0; i < bytes_read; ++i) 25470b57cec5SDimitry Andric response.PutHex8(buf[i]); 25480b57cec5SDimitry Andric } 25490b57cec5SDimitry Andric 25500b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 25510b57cec5SDimitry Andric } 25520b57cec5SDimitry Andric 25530b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 2554e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) { 255581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 2556e8d8bef9SDimitry Andric 2557fe6060f1SDimitry Andric if (!m_current_process || 2558fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 2559e8d8bef9SDimitry Andric LLDB_LOGF( 2560e8d8bef9SDimitry Andric log, 2561e8d8bef9SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 2562e8d8bef9SDimitry Andric __FUNCTION__); 2563e8d8bef9SDimitry Andric return SendErrorResponse(0x15); 2564e8d8bef9SDimitry Andric } 2565e8d8bef9SDimitry Andric 2566e8d8bef9SDimitry Andric // Parse out the memory address. 2567e8d8bef9SDimitry Andric packet.SetFilePos(strlen("_M")); 2568e8d8bef9SDimitry Andric if (packet.GetBytesLeft() < 1) 2569e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Too short _M packet"); 2570e8d8bef9SDimitry Andric 2571e8d8bef9SDimitry Andric const lldb::addr_t size = packet.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); 2572e8d8bef9SDimitry Andric if (size == LLDB_INVALID_ADDRESS) 2573e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Address not valid"); 2574e8d8bef9SDimitry Andric if (packet.GetChar() != ',') 2575e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Bad packet"); 2576e8d8bef9SDimitry Andric Permissions perms = {}; 2577e8d8bef9SDimitry Andric while (packet.GetBytesLeft() > 0) { 2578e8d8bef9SDimitry Andric switch (packet.GetChar()) { 2579e8d8bef9SDimitry Andric case 'r': 2580e8d8bef9SDimitry Andric perms |= ePermissionsReadable; 2581e8d8bef9SDimitry Andric break; 2582e8d8bef9SDimitry Andric case 'w': 2583e8d8bef9SDimitry Andric perms |= ePermissionsWritable; 2584e8d8bef9SDimitry Andric break; 2585e8d8bef9SDimitry Andric case 'x': 2586e8d8bef9SDimitry Andric perms |= ePermissionsExecutable; 2587e8d8bef9SDimitry Andric break; 2588e8d8bef9SDimitry Andric default: 2589e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Bad permissions"); 2590e8d8bef9SDimitry Andric } 2591e8d8bef9SDimitry Andric } 2592e8d8bef9SDimitry Andric 2593fe6060f1SDimitry Andric llvm::Expected<addr_t> addr = m_current_process->AllocateMemory(size, perms); 2594e8d8bef9SDimitry Andric if (!addr) 2595e8d8bef9SDimitry Andric return SendErrorResponse(addr.takeError()); 2596e8d8bef9SDimitry Andric 2597e8d8bef9SDimitry Andric StreamGDBRemote response; 2598e8d8bef9SDimitry Andric response.PutHex64(*addr); 2599e8d8bef9SDimitry Andric return SendPacketNoLock(response.GetString()); 2600e8d8bef9SDimitry Andric } 2601e8d8bef9SDimitry Andric 2602e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 2603e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) { 260481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 2605e8d8bef9SDimitry Andric 2606fe6060f1SDimitry Andric if (!m_current_process || 2607fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 2608e8d8bef9SDimitry Andric LLDB_LOGF( 2609e8d8bef9SDimitry Andric log, 2610e8d8bef9SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 2611e8d8bef9SDimitry Andric __FUNCTION__); 2612e8d8bef9SDimitry Andric return SendErrorResponse(0x15); 2613e8d8bef9SDimitry Andric } 2614e8d8bef9SDimitry Andric 2615e8d8bef9SDimitry Andric // Parse out the memory address. 2616e8d8bef9SDimitry Andric packet.SetFilePos(strlen("_m")); 2617e8d8bef9SDimitry Andric if (packet.GetBytesLeft() < 1) 2618e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Too short m packet"); 2619e8d8bef9SDimitry Andric 2620e8d8bef9SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); 2621e8d8bef9SDimitry Andric if (addr == LLDB_INVALID_ADDRESS) 2622e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Address not valid"); 2623e8d8bef9SDimitry Andric 2624fe6060f1SDimitry Andric if (llvm::Error Err = m_current_process->DeallocateMemory(addr)) 2625e8d8bef9SDimitry Andric return SendErrorResponse(std::move(Err)); 2626e8d8bef9SDimitry Andric 2627e8d8bef9SDimitry Andric return SendOKResponse(); 2628e8d8bef9SDimitry Andric } 2629e8d8bef9SDimitry Andric 2630e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 26310b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { 263281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 26330b57cec5SDimitry Andric 2634fe6060f1SDimitry Andric if (!m_current_process || 2635fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 26369dba64beSDimitry Andric LLDB_LOGF( 26379dba64beSDimitry Andric log, 26380b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 26390b57cec5SDimitry Andric __FUNCTION__); 26400b57cec5SDimitry Andric return SendErrorResponse(0x15); 26410b57cec5SDimitry Andric } 26420b57cec5SDimitry Andric 26430b57cec5SDimitry Andric // Parse out the memory address. 26440b57cec5SDimitry Andric packet.SetFilePos(strlen("M")); 26450b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 26460b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short M packet"); 26470b57cec5SDimitry Andric 26480b57cec5SDimitry Andric // Read the address. Punting on validation. 26490b57cec5SDimitry Andric // FIXME replace with Hex U64 read with no default value that fails on failed 26500b57cec5SDimitry Andric // read. 26510b57cec5SDimitry Andric const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0); 26520b57cec5SDimitry Andric 26530b57cec5SDimitry Andric // Validate comma. 26540b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) 26550b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Comma sep missing in M packet"); 26560b57cec5SDimitry Andric 26570b57cec5SDimitry Andric // Get # bytes to read. 26580b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 26590b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Length missing in M packet"); 26600b57cec5SDimitry Andric 26610b57cec5SDimitry Andric const uint64_t byte_count = packet.GetHexMaxU64(false, 0); 26620b57cec5SDimitry Andric if (byte_count == 0) { 26630b57cec5SDimitry Andric LLDB_LOG(log, "nothing to write: zero-length packet"); 26640b57cec5SDimitry Andric return PacketResult::Success; 26650b57cec5SDimitry Andric } 26660b57cec5SDimitry Andric 26670b57cec5SDimitry Andric // Validate colon. 26680b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':')) 26690b57cec5SDimitry Andric return SendIllFormedResponse( 26700b57cec5SDimitry Andric packet, "Comma sep missing in M packet after byte length"); 26710b57cec5SDimitry Andric 26720b57cec5SDimitry Andric // Allocate the conversion buffer. 26730b57cec5SDimitry Andric std::vector<uint8_t> buf(byte_count, 0); 26740b57cec5SDimitry Andric if (buf.empty()) 26750b57cec5SDimitry Andric return SendErrorResponse(0x78); 26760b57cec5SDimitry Andric 26770b57cec5SDimitry Andric // Convert the hex memory write contents to bytes. 26780b57cec5SDimitry Andric StreamGDBRemote response; 26790b57cec5SDimitry Andric const uint64_t convert_count = packet.GetHexBytes(buf, 0); 26800b57cec5SDimitry Andric if (convert_count != byte_count) { 26810b57cec5SDimitry Andric LLDB_LOG(log, 26820b57cec5SDimitry Andric "pid {0} mem {1:x}: asked to write {2} bytes, but only found {3} " 26830b57cec5SDimitry Andric "to convert.", 2684fe6060f1SDimitry Andric m_current_process->GetID(), write_addr, byte_count, convert_count); 26850b57cec5SDimitry Andric return SendIllFormedResponse(packet, "M content byte length specified did " 26860b57cec5SDimitry Andric "not match hex-encoded content " 26870b57cec5SDimitry Andric "length"); 26880b57cec5SDimitry Andric } 26890b57cec5SDimitry Andric 26900b57cec5SDimitry Andric // Write the process memory. 26910b57cec5SDimitry Andric size_t bytes_written = 0; 2692fe6060f1SDimitry Andric Status error = m_current_process->WriteMemory(write_addr, &buf[0], byte_count, 2693fe6060f1SDimitry Andric bytes_written); 26940b57cec5SDimitry Andric if (error.Fail()) { 26950b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} mem {1:x}: failed to write. Error: {2}", 2696fe6060f1SDimitry Andric m_current_process->GetID(), write_addr, error); 26970b57cec5SDimitry Andric return SendErrorResponse(0x09); 26980b57cec5SDimitry Andric } 26990b57cec5SDimitry Andric 27000b57cec5SDimitry Andric if (bytes_written == 0) { 27010b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} mem {1:x}: wrote 0 of {2} requested bytes", 2702fe6060f1SDimitry Andric m_current_process->GetID(), write_addr, byte_count); 27030b57cec5SDimitry Andric return SendErrorResponse(0x09); 27040b57cec5SDimitry Andric } 27050b57cec5SDimitry Andric 27060b57cec5SDimitry Andric return SendOKResponse(); 27070b57cec5SDimitry Andric } 27080b57cec5SDimitry Andric 27090b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 27100b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( 27110b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 271281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 27130b57cec5SDimitry Andric 27140b57cec5SDimitry Andric // Currently only the NativeProcessProtocol knows if it can handle a 27150b57cec5SDimitry Andric // qMemoryRegionInfoSupported request, but we're not guaranteed to be 27160b57cec5SDimitry Andric // attached to a process. For now we'll assume the client only asks this 27170b57cec5SDimitry Andric // when a process is being debugged. 27180b57cec5SDimitry Andric 27190b57cec5SDimitry Andric // Ensure we have a process running; otherwise, we can't figure this out 27200b57cec5SDimitry Andric // since we won't have a NativeProcessProtocol. 2721fe6060f1SDimitry Andric if (!m_current_process || 2722fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 27239dba64beSDimitry Andric LLDB_LOGF( 27249dba64beSDimitry Andric log, 27250b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 27260b57cec5SDimitry Andric __FUNCTION__); 27270b57cec5SDimitry Andric return SendErrorResponse(0x15); 27280b57cec5SDimitry Andric } 27290b57cec5SDimitry Andric 27300b57cec5SDimitry Andric // Test if we can get any region back when asking for the region around NULL. 27310b57cec5SDimitry Andric MemoryRegionInfo region_info; 2732fe6060f1SDimitry Andric const Status error = m_current_process->GetMemoryRegionInfo(0, region_info); 27330b57cec5SDimitry Andric if (error.Fail()) { 27340b57cec5SDimitry Andric // We don't support memory region info collection for this 27350b57cec5SDimitry Andric // NativeProcessProtocol. 27360b57cec5SDimitry Andric return SendUnimplementedResponse(""); 27370b57cec5SDimitry Andric } 27380b57cec5SDimitry Andric 27390b57cec5SDimitry Andric return SendOKResponse(); 27400b57cec5SDimitry Andric } 27410b57cec5SDimitry Andric 27420b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 27430b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( 27440b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 274581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 27460b57cec5SDimitry Andric 27470b57cec5SDimitry Andric // Ensure we have a process. 2748fe6060f1SDimitry Andric if (!m_current_process || 2749fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 27509dba64beSDimitry Andric LLDB_LOGF( 27519dba64beSDimitry Andric log, 27520b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 27530b57cec5SDimitry Andric __FUNCTION__); 27540b57cec5SDimitry Andric return SendErrorResponse(0x15); 27550b57cec5SDimitry Andric } 27560b57cec5SDimitry Andric 27570b57cec5SDimitry Andric // Parse out the memory address. 27580b57cec5SDimitry Andric packet.SetFilePos(strlen("qMemoryRegionInfo:")); 27590b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 27600b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet"); 27610b57cec5SDimitry Andric 27620b57cec5SDimitry Andric // Read the address. Punting on validation. 27630b57cec5SDimitry Andric const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0); 27640b57cec5SDimitry Andric 27650b57cec5SDimitry Andric StreamGDBRemote response; 27660b57cec5SDimitry Andric 27670b57cec5SDimitry Andric // Get the memory region info for the target address. 27680b57cec5SDimitry Andric MemoryRegionInfo region_info; 27690b57cec5SDimitry Andric const Status error = 2770fe6060f1SDimitry Andric m_current_process->GetMemoryRegionInfo(read_addr, region_info); 27710b57cec5SDimitry Andric if (error.Fail()) { 27720b57cec5SDimitry Andric // Return the error message. 27730b57cec5SDimitry Andric 27740b57cec5SDimitry Andric response.PutCString("error:"); 27750b57cec5SDimitry Andric response.PutStringAsRawHex8(error.AsCString()); 27760b57cec5SDimitry Andric response.PutChar(';'); 27770b57cec5SDimitry Andric } else { 27780b57cec5SDimitry Andric // Range start and size. 27790b57cec5SDimitry Andric response.Printf("start:%" PRIx64 ";size:%" PRIx64 ";", 27800b57cec5SDimitry Andric region_info.GetRange().GetRangeBase(), 27810b57cec5SDimitry Andric region_info.GetRange().GetByteSize()); 27820b57cec5SDimitry Andric 27830b57cec5SDimitry Andric // Permissions. 27840b57cec5SDimitry Andric if (region_info.GetReadable() || region_info.GetWritable() || 27850b57cec5SDimitry Andric region_info.GetExecutable()) { 27860b57cec5SDimitry Andric // Write permissions info. 27870b57cec5SDimitry Andric response.PutCString("permissions:"); 27880b57cec5SDimitry Andric 27890b57cec5SDimitry Andric if (region_info.GetReadable()) 27900b57cec5SDimitry Andric response.PutChar('r'); 27910b57cec5SDimitry Andric if (region_info.GetWritable()) 27920b57cec5SDimitry Andric response.PutChar('w'); 27930b57cec5SDimitry Andric if (region_info.GetExecutable()) 27940b57cec5SDimitry Andric response.PutChar('x'); 27950b57cec5SDimitry Andric 27960b57cec5SDimitry Andric response.PutChar(';'); 27970b57cec5SDimitry Andric } 27980b57cec5SDimitry Andric 2799e8d8bef9SDimitry Andric // Flags 2800e8d8bef9SDimitry Andric MemoryRegionInfo::OptionalBool memory_tagged = 2801e8d8bef9SDimitry Andric region_info.GetMemoryTagged(); 2802e8d8bef9SDimitry Andric if (memory_tagged != MemoryRegionInfo::eDontKnow) { 2803e8d8bef9SDimitry Andric response.PutCString("flags:"); 2804e8d8bef9SDimitry Andric if (memory_tagged == MemoryRegionInfo::eYes) { 2805e8d8bef9SDimitry Andric response.PutCString("mt"); 2806e8d8bef9SDimitry Andric } 2807e8d8bef9SDimitry Andric response.PutChar(';'); 2808e8d8bef9SDimitry Andric } 2809e8d8bef9SDimitry Andric 28100b57cec5SDimitry Andric // Name 28110b57cec5SDimitry Andric ConstString name = region_info.GetName(); 28120b57cec5SDimitry Andric if (name) { 28130b57cec5SDimitry Andric response.PutCString("name:"); 28145ffd83dbSDimitry Andric response.PutStringAsRawHex8(name.GetStringRef()); 28150b57cec5SDimitry Andric response.PutChar(';'); 28160b57cec5SDimitry Andric } 28170b57cec5SDimitry Andric } 28180b57cec5SDimitry Andric 28190b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 28200b57cec5SDimitry Andric } 28210b57cec5SDimitry Andric 28220b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 28230b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { 28240b57cec5SDimitry Andric // Ensure we have a process. 2825fe6060f1SDimitry Andric if (!m_current_process || 2826fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 282781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 28280b57cec5SDimitry Andric LLDB_LOG(log, "failed, no process available"); 28290b57cec5SDimitry Andric return SendErrorResponse(0x15); 28300b57cec5SDimitry Andric } 28310b57cec5SDimitry Andric 28320b57cec5SDimitry Andric // Parse out software or hardware breakpoint or watchpoint requested. 28330b57cec5SDimitry Andric packet.SetFilePos(strlen("Z")); 28340b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 28350b57cec5SDimitry Andric return SendIllFormedResponse( 28360b57cec5SDimitry Andric packet, "Too short Z packet, missing software/hardware specifier"); 28370b57cec5SDimitry Andric 28380b57cec5SDimitry Andric bool want_breakpoint = true; 28390b57cec5SDimitry Andric bool want_hardware = false; 28400b57cec5SDimitry Andric uint32_t watch_flags = 0; 28410b57cec5SDimitry Andric 28420b57cec5SDimitry Andric const GDBStoppointType stoppoint_type = 28430b57cec5SDimitry Andric GDBStoppointType(packet.GetS32(eStoppointInvalid)); 28440b57cec5SDimitry Andric switch (stoppoint_type) { 28450b57cec5SDimitry Andric case eBreakpointSoftware: 28460b57cec5SDimitry Andric want_hardware = false; 28470b57cec5SDimitry Andric want_breakpoint = true; 28480b57cec5SDimitry Andric break; 28490b57cec5SDimitry Andric case eBreakpointHardware: 28500b57cec5SDimitry Andric want_hardware = true; 28510b57cec5SDimitry Andric want_breakpoint = true; 28520b57cec5SDimitry Andric break; 28530b57cec5SDimitry Andric case eWatchpointWrite: 28540b57cec5SDimitry Andric watch_flags = 1; 28550b57cec5SDimitry Andric want_hardware = true; 28560b57cec5SDimitry Andric want_breakpoint = false; 28570b57cec5SDimitry Andric break; 28580b57cec5SDimitry Andric case eWatchpointRead: 28590b57cec5SDimitry Andric watch_flags = 2; 28600b57cec5SDimitry Andric want_hardware = true; 28610b57cec5SDimitry Andric want_breakpoint = false; 28620b57cec5SDimitry Andric break; 28630b57cec5SDimitry Andric case eWatchpointReadWrite: 28640b57cec5SDimitry Andric watch_flags = 3; 28650b57cec5SDimitry Andric want_hardware = true; 28660b57cec5SDimitry Andric want_breakpoint = false; 28670b57cec5SDimitry Andric break; 28680b57cec5SDimitry Andric case eStoppointInvalid: 28690b57cec5SDimitry Andric return SendIllFormedResponse( 28700b57cec5SDimitry Andric packet, "Z packet had invalid software/hardware specifier"); 28710b57cec5SDimitry Andric } 28720b57cec5SDimitry Andric 28730b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') 28740b57cec5SDimitry Andric return SendIllFormedResponse( 28750b57cec5SDimitry Andric packet, "Malformed Z packet, expecting comma after stoppoint type"); 28760b57cec5SDimitry Andric 28770b57cec5SDimitry Andric // Parse out the stoppoint address. 28780b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 28790b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short Z packet, missing address"); 28800b57cec5SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(false, 0); 28810b57cec5SDimitry Andric 28820b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') 28830b57cec5SDimitry Andric return SendIllFormedResponse( 28840b57cec5SDimitry Andric packet, "Malformed Z packet, expecting comma after address"); 28850b57cec5SDimitry Andric 28860b57cec5SDimitry Andric // Parse out the stoppoint size (i.e. size hint for opcode size). 28870b57cec5SDimitry Andric const uint32_t size = 28880b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 28890b57cec5SDimitry Andric if (size == std::numeric_limits<uint32_t>::max()) 28900b57cec5SDimitry Andric return SendIllFormedResponse( 28910b57cec5SDimitry Andric packet, "Malformed Z packet, failed to parse size argument"); 28920b57cec5SDimitry Andric 28930b57cec5SDimitry Andric if (want_breakpoint) { 28940b57cec5SDimitry Andric // Try to set the breakpoint. 28950b57cec5SDimitry Andric const Status error = 2896fe6060f1SDimitry Andric m_current_process->SetBreakpoint(addr, size, want_hardware); 28970b57cec5SDimitry Andric if (error.Success()) 28980b57cec5SDimitry Andric return SendOKResponse(); 289981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Breakpoints); 29000b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to set breakpoint: {1}", 2901fe6060f1SDimitry Andric m_current_process->GetID(), error); 29020b57cec5SDimitry Andric return SendErrorResponse(0x09); 29030b57cec5SDimitry Andric } else { 29040b57cec5SDimitry Andric // Try to set the watchpoint. 2905fe6060f1SDimitry Andric const Status error = m_current_process->SetWatchpoint( 29060b57cec5SDimitry Andric addr, size, watch_flags, want_hardware); 29070b57cec5SDimitry Andric if (error.Success()) 29080b57cec5SDimitry Andric return SendOKResponse(); 290981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Watchpoints); 29100b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to set watchpoint: {1}", 2911fe6060f1SDimitry Andric m_current_process->GetID(), error); 29120b57cec5SDimitry Andric return SendErrorResponse(0x09); 29130b57cec5SDimitry Andric } 29140b57cec5SDimitry Andric } 29150b57cec5SDimitry Andric 29160b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 29170b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { 29180b57cec5SDimitry Andric // Ensure we have a process. 2919fe6060f1SDimitry Andric if (!m_current_process || 2920fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 292181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 29220b57cec5SDimitry Andric LLDB_LOG(log, "failed, no process available"); 29230b57cec5SDimitry Andric return SendErrorResponse(0x15); 29240b57cec5SDimitry Andric } 29250b57cec5SDimitry Andric 29260b57cec5SDimitry Andric // Parse out software or hardware breakpoint or watchpoint requested. 29270b57cec5SDimitry Andric packet.SetFilePos(strlen("z")); 29280b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 29290b57cec5SDimitry Andric return SendIllFormedResponse( 29300b57cec5SDimitry Andric packet, "Too short z packet, missing software/hardware specifier"); 29310b57cec5SDimitry Andric 29320b57cec5SDimitry Andric bool want_breakpoint = true; 29330b57cec5SDimitry Andric bool want_hardware = false; 29340b57cec5SDimitry Andric 29350b57cec5SDimitry Andric const GDBStoppointType stoppoint_type = 29360b57cec5SDimitry Andric GDBStoppointType(packet.GetS32(eStoppointInvalid)); 29370b57cec5SDimitry Andric switch (stoppoint_type) { 29380b57cec5SDimitry Andric case eBreakpointHardware: 29390b57cec5SDimitry Andric want_breakpoint = true; 29400b57cec5SDimitry Andric want_hardware = true; 29410b57cec5SDimitry Andric break; 29420b57cec5SDimitry Andric case eBreakpointSoftware: 29430b57cec5SDimitry Andric want_breakpoint = true; 29440b57cec5SDimitry Andric break; 29450b57cec5SDimitry Andric case eWatchpointWrite: 29460b57cec5SDimitry Andric want_breakpoint = false; 29470b57cec5SDimitry Andric break; 29480b57cec5SDimitry Andric case eWatchpointRead: 29490b57cec5SDimitry Andric want_breakpoint = false; 29500b57cec5SDimitry Andric break; 29510b57cec5SDimitry Andric case eWatchpointReadWrite: 29520b57cec5SDimitry Andric want_breakpoint = false; 29530b57cec5SDimitry Andric break; 29540b57cec5SDimitry Andric default: 29550b57cec5SDimitry Andric return SendIllFormedResponse( 29560b57cec5SDimitry Andric packet, "z packet had invalid software/hardware specifier"); 29570b57cec5SDimitry Andric } 29580b57cec5SDimitry Andric 29590b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') 29600b57cec5SDimitry Andric return SendIllFormedResponse( 29610b57cec5SDimitry Andric packet, "Malformed z packet, expecting comma after stoppoint type"); 29620b57cec5SDimitry Andric 29630b57cec5SDimitry Andric // Parse out the stoppoint address. 29640b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 29650b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short z packet, missing address"); 29660b57cec5SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(false, 0); 29670b57cec5SDimitry Andric 29680b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') 29690b57cec5SDimitry Andric return SendIllFormedResponse( 29700b57cec5SDimitry Andric packet, "Malformed z packet, expecting comma after address"); 29710b57cec5SDimitry Andric 29720b57cec5SDimitry Andric /* 29730b57cec5SDimitry Andric // Parse out the stoppoint size (i.e. size hint for opcode size). 29740b57cec5SDimitry Andric const uint32_t size = packet.GetHexMaxU32 (false, 29750b57cec5SDimitry Andric std::numeric_limits<uint32_t>::max ()); 29760b57cec5SDimitry Andric if (size == std::numeric_limits<uint32_t>::max ()) 29770b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Malformed z packet, failed to parse 29780b57cec5SDimitry Andric size argument"); 29790b57cec5SDimitry Andric */ 29800b57cec5SDimitry Andric 29810b57cec5SDimitry Andric if (want_breakpoint) { 29820b57cec5SDimitry Andric // Try to clear the breakpoint. 29830b57cec5SDimitry Andric const Status error = 2984fe6060f1SDimitry Andric m_current_process->RemoveBreakpoint(addr, want_hardware); 29850b57cec5SDimitry Andric if (error.Success()) 29860b57cec5SDimitry Andric return SendOKResponse(); 298781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Breakpoints); 29880b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to remove breakpoint: {1}", 2989fe6060f1SDimitry Andric m_current_process->GetID(), error); 29900b57cec5SDimitry Andric return SendErrorResponse(0x09); 29910b57cec5SDimitry Andric } else { 29920b57cec5SDimitry Andric // Try to clear the watchpoint. 2993fe6060f1SDimitry Andric const Status error = m_current_process->RemoveWatchpoint(addr); 29940b57cec5SDimitry Andric if (error.Success()) 29950b57cec5SDimitry Andric return SendOKResponse(); 299681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Watchpoints); 29970b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to remove watchpoint: {1}", 2998fe6060f1SDimitry Andric m_current_process->GetID(), error); 29990b57cec5SDimitry Andric return SendErrorResponse(0x09); 30000b57cec5SDimitry Andric } 30010b57cec5SDimitry Andric } 30020b57cec5SDimitry Andric 30030b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 30040b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { 300581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 30060b57cec5SDimitry Andric 30070b57cec5SDimitry Andric // Ensure we have a process. 3008fe6060f1SDimitry Andric if (!m_continue_process || 3009fe6060f1SDimitry Andric (m_continue_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 30109dba64beSDimitry Andric LLDB_LOGF( 30119dba64beSDimitry Andric log, 30120b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 30130b57cec5SDimitry Andric __FUNCTION__); 30140b57cec5SDimitry Andric return SendErrorResponse(0x32); 30150b57cec5SDimitry Andric } 30160b57cec5SDimitry Andric 30170b57cec5SDimitry Andric // We first try to use a continue thread id. If any one or any all set, use 30180b57cec5SDimitry Andric // the current thread. Bail out if we don't have a thread id. 30190b57cec5SDimitry Andric lldb::tid_t tid = GetContinueThreadID(); 30200b57cec5SDimitry Andric if (tid == 0 || tid == LLDB_INVALID_THREAD_ID) 30210b57cec5SDimitry Andric tid = GetCurrentThreadID(); 30220b57cec5SDimitry Andric if (tid == LLDB_INVALID_THREAD_ID) 30230b57cec5SDimitry Andric return SendErrorResponse(0x33); 30240b57cec5SDimitry Andric 30250b57cec5SDimitry Andric // Double check that we have such a thread. 30260b57cec5SDimitry Andric // TODO investigate: on MacOSX we might need to do an UpdateThreads () here. 3027fe6060f1SDimitry Andric NativeThreadProtocol *thread = m_continue_process->GetThreadByID(tid); 30280b57cec5SDimitry Andric if (!thread) 30290b57cec5SDimitry Andric return SendErrorResponse(0x33); 30300b57cec5SDimitry Andric 30310b57cec5SDimitry Andric // Create the step action for the given thread. 30329dba64beSDimitry Andric ResumeAction action = {tid, eStateStepping, LLDB_INVALID_SIGNAL_NUMBER}; 30330b57cec5SDimitry Andric 30340b57cec5SDimitry Andric // Setup the actions list. 30350b57cec5SDimitry Andric ResumeActionList actions; 30360b57cec5SDimitry Andric actions.Append(action); 30370b57cec5SDimitry Andric 30380b57cec5SDimitry Andric // All other threads stop while we're single stepping a thread. 30390b57cec5SDimitry Andric actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 3040fcaf7f86SDimitry Andric 3041fcaf7f86SDimitry Andric PacketResult resume_res = ResumeProcess(*m_continue_process, actions); 3042fcaf7f86SDimitry Andric if (resume_res != PacketResult::Success) 3043fcaf7f86SDimitry Andric return resume_res; 30440b57cec5SDimitry Andric 304581ad6265SDimitry Andric // No response here, unless in non-stop mode. 304681ad6265SDimitry Andric // Otherwise, the stop or exit will come from the resulting action. 304781ad6265SDimitry Andric return SendContinueSuccessResponse(); 30480b57cec5SDimitry Andric } 30490b57cec5SDimitry Andric 30500b57cec5SDimitry Andric llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 30515ffd83dbSDimitry Andric GDBRemoteCommunicationServerLLGS::BuildTargetXml() { 30525ffd83dbSDimitry Andric // Ensure we have a thread. 3053fe6060f1SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0); 30545ffd83dbSDimitry Andric if (!thread) 30555ffd83dbSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 30565ffd83dbSDimitry Andric "No thread available"); 30575ffd83dbSDimitry Andric 305881ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 30595ffd83dbSDimitry Andric // Get the register context for the first thread. 30605ffd83dbSDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 30615ffd83dbSDimitry Andric 30625ffd83dbSDimitry Andric StreamString response; 30635ffd83dbSDimitry Andric 30645ffd83dbSDimitry Andric response.Printf("<?xml version=\"1.0\"?>"); 30655ffd83dbSDimitry Andric response.Printf("<target version=\"1.0\">"); 30665ffd83dbSDimitry Andric 30675ffd83dbSDimitry Andric response.Printf("<architecture>%s</architecture>", 3068fe6060f1SDimitry Andric m_current_process->GetArchitecture() 30695ffd83dbSDimitry Andric .GetTriple() 30705ffd83dbSDimitry Andric .getArchName() 30715ffd83dbSDimitry Andric .str() 30725ffd83dbSDimitry Andric .c_str()); 30735ffd83dbSDimitry Andric 30745ffd83dbSDimitry Andric response.Printf("<feature>"); 30755ffd83dbSDimitry Andric 30765ffd83dbSDimitry Andric const int registers_count = reg_context.GetUserRegisterCount(); 30775ffd83dbSDimitry Andric for (int reg_index = 0; reg_index < registers_count; reg_index++) { 30785ffd83dbSDimitry Andric const RegisterInfo *reg_info = 30795ffd83dbSDimitry Andric reg_context.GetRegisterInfoAtIndex(reg_index); 30805ffd83dbSDimitry Andric 30815ffd83dbSDimitry Andric if (!reg_info) { 30825ffd83dbSDimitry Andric LLDB_LOGF(log, 30835ffd83dbSDimitry Andric "%s failed to get register info for register index %" PRIu32, 30845ffd83dbSDimitry Andric "target.xml", reg_index); 30855ffd83dbSDimitry Andric continue; 30865ffd83dbSDimitry Andric } 30875ffd83dbSDimitry Andric 3088e8d8bef9SDimitry Andric response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" regnum=\"%d\" ", 3089e8d8bef9SDimitry Andric reg_info->name, reg_info->byte_size * 8, reg_index); 3090e8d8bef9SDimitry Andric 3091e8d8bef9SDimitry Andric if (!reg_context.RegisterOffsetIsDynamic()) 3092e8d8bef9SDimitry Andric response.Printf("offset=\"%" PRIu32 "\" ", reg_info->byte_offset); 30935ffd83dbSDimitry Andric 30945ffd83dbSDimitry Andric if (reg_info->alt_name && reg_info->alt_name[0]) 30955ffd83dbSDimitry Andric response.Printf("altname=\"%s\" ", reg_info->alt_name); 30965ffd83dbSDimitry Andric 30975ffd83dbSDimitry Andric llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info); 30985ffd83dbSDimitry Andric if (!encoding.empty()) 30995ffd83dbSDimitry Andric response << "encoding=\"" << encoding << "\" "; 31005ffd83dbSDimitry Andric 31015ffd83dbSDimitry Andric llvm::StringRef format = GetFormatNameOrEmpty(*reg_info); 31025ffd83dbSDimitry Andric if (!format.empty()) 31035ffd83dbSDimitry Andric response << "format=\"" << format << "\" "; 31045ffd83dbSDimitry Andric 31055ffd83dbSDimitry Andric const char *const register_set_name = 31065ffd83dbSDimitry Andric reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); 31075ffd83dbSDimitry Andric if (register_set_name) 31085ffd83dbSDimitry Andric response << "group=\"" << register_set_name << "\" "; 31095ffd83dbSDimitry Andric 31105ffd83dbSDimitry Andric if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != 31115ffd83dbSDimitry Andric LLDB_INVALID_REGNUM) 31125ffd83dbSDimitry Andric response.Printf("ehframe_regnum=\"%" PRIu32 "\" ", 31135ffd83dbSDimitry Andric reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); 31145ffd83dbSDimitry Andric 31155ffd83dbSDimitry Andric if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != 31165ffd83dbSDimitry Andric LLDB_INVALID_REGNUM) 31175ffd83dbSDimitry Andric response.Printf("dwarf_regnum=\"%" PRIu32 "\" ", 31185ffd83dbSDimitry Andric reg_info->kinds[RegisterKind::eRegisterKindDWARF]); 31195ffd83dbSDimitry Andric 31205ffd83dbSDimitry Andric llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info); 31215ffd83dbSDimitry Andric if (!kind_generic.empty()) 31225ffd83dbSDimitry Andric response << "generic=\"" << kind_generic << "\" "; 31235ffd83dbSDimitry Andric 31245ffd83dbSDimitry Andric if (reg_info->value_regs && 31255ffd83dbSDimitry Andric reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { 31265ffd83dbSDimitry Andric response.PutCString("value_regnums=\""); 31275ffd83dbSDimitry Andric CollectRegNums(reg_info->value_regs, response, false); 31285ffd83dbSDimitry Andric response.Printf("\" "); 31295ffd83dbSDimitry Andric } 31305ffd83dbSDimitry Andric 31315ffd83dbSDimitry Andric if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { 31325ffd83dbSDimitry Andric response.PutCString("invalidate_regnums=\""); 31335ffd83dbSDimitry Andric CollectRegNums(reg_info->invalidate_regs, response, false); 31345ffd83dbSDimitry Andric response.Printf("\" "); 31355ffd83dbSDimitry Andric } 31365ffd83dbSDimitry Andric 31375ffd83dbSDimitry Andric response.Printf("/>"); 31385ffd83dbSDimitry Andric } 31395ffd83dbSDimitry Andric 31405ffd83dbSDimitry Andric response.Printf("</feature>"); 31415ffd83dbSDimitry Andric response.Printf("</target>"); 31425ffd83dbSDimitry Andric return MemoryBuffer::getMemBufferCopy(response.GetString(), "target.xml"); 31435ffd83dbSDimitry Andric } 31445ffd83dbSDimitry Andric 31455ffd83dbSDimitry Andric llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 31460b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object, 31470b57cec5SDimitry Andric llvm::StringRef annex) { 31480b57cec5SDimitry Andric // Make sure we have a valid process. 3149fe6060f1SDimitry Andric if (!m_current_process || 3150fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 31510b57cec5SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 31520b57cec5SDimitry Andric "No process available"); 31530b57cec5SDimitry Andric } 31540b57cec5SDimitry Andric 31555ffd83dbSDimitry Andric if (object == "auxv") { 31560b57cec5SDimitry Andric // Grab the auxv data. 3157fe6060f1SDimitry Andric auto buffer_or_error = m_current_process->GetAuxvData(); 31580b57cec5SDimitry Andric if (!buffer_or_error) 31590b57cec5SDimitry Andric return llvm::errorCodeToError(buffer_or_error.getError()); 31600b57cec5SDimitry Andric return std::move(*buffer_or_error); 31610b57cec5SDimitry Andric } 31620b57cec5SDimitry Andric 316304eeddc0SDimitry Andric if (object == "siginfo") { 316404eeddc0SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); 316504eeddc0SDimitry Andric if (!thread) 316604eeddc0SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 316704eeddc0SDimitry Andric "no current thread"); 316804eeddc0SDimitry Andric 316904eeddc0SDimitry Andric auto buffer_or_error = thread->GetSiginfo(); 317004eeddc0SDimitry Andric if (!buffer_or_error) 317104eeddc0SDimitry Andric return buffer_or_error.takeError(); 317204eeddc0SDimitry Andric return std::move(*buffer_or_error); 317304eeddc0SDimitry Andric } 317404eeddc0SDimitry Andric 31759dba64beSDimitry Andric if (object == "libraries-svr4") { 3176fe6060f1SDimitry Andric auto library_list = m_current_process->GetLoadedSVR4Libraries(); 31779dba64beSDimitry Andric if (!library_list) 31789dba64beSDimitry Andric return library_list.takeError(); 31799dba64beSDimitry Andric 31809dba64beSDimitry Andric StreamString response; 31819dba64beSDimitry Andric response.Printf("<library-list-svr4 version=\"1.0\">"); 31829dba64beSDimitry Andric for (auto const &library : *library_list) { 31839dba64beSDimitry Andric response.Printf("<library name=\"%s\" ", 31849dba64beSDimitry Andric XMLEncodeAttributeValue(library.name.c_str()).c_str()); 31859dba64beSDimitry Andric response.Printf("lm=\"0x%" PRIx64 "\" ", library.link_map); 31869dba64beSDimitry Andric response.Printf("l_addr=\"0x%" PRIx64 "\" ", library.base_addr); 31879dba64beSDimitry Andric response.Printf("l_ld=\"0x%" PRIx64 "\" />", library.ld_addr); 31889dba64beSDimitry Andric } 31899dba64beSDimitry Andric response.Printf("</library-list-svr4>"); 31909dba64beSDimitry Andric return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__); 31919dba64beSDimitry Andric } 31929dba64beSDimitry Andric 31935ffd83dbSDimitry Andric if (object == "features" && annex == "target.xml") 31945ffd83dbSDimitry Andric return BuildTargetXml(); 31955ffd83dbSDimitry Andric 3196e8d8bef9SDimitry Andric return llvm::make_error<UnimplementedError>(); 31970b57cec5SDimitry Andric } 31980b57cec5SDimitry Andric 31990b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 32000b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qXfer( 32010b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 32020b57cec5SDimitry Andric SmallVector<StringRef, 5> fields; 32030b57cec5SDimitry Andric // The packet format is "qXfer:<object>:<action>:<annex>:offset,length" 32040b57cec5SDimitry Andric StringRef(packet.GetStringRef()).split(fields, ':', 4); 32050b57cec5SDimitry Andric if (fields.size() != 5) 32060b57cec5SDimitry Andric return SendIllFormedResponse(packet, "malformed qXfer packet"); 32070b57cec5SDimitry Andric StringRef &xfer_object = fields[1]; 32080b57cec5SDimitry Andric StringRef &xfer_action = fields[2]; 32090b57cec5SDimitry Andric StringRef &xfer_annex = fields[3]; 32100b57cec5SDimitry Andric StringExtractor offset_data(fields[4]); 32110b57cec5SDimitry Andric if (xfer_action != "read") 32120b57cec5SDimitry Andric return SendUnimplementedResponse("qXfer action not supported"); 32130b57cec5SDimitry Andric // Parse offset. 32140b57cec5SDimitry Andric const uint64_t xfer_offset = 32150b57cec5SDimitry Andric offset_data.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max()); 32160b57cec5SDimitry Andric if (xfer_offset == std::numeric_limits<uint64_t>::max()) 32170b57cec5SDimitry Andric return SendIllFormedResponse(packet, "qXfer packet missing offset"); 32180b57cec5SDimitry Andric // Parse out comma. 32190b57cec5SDimitry Andric if (offset_data.GetChar() != ',') 32200b57cec5SDimitry Andric return SendIllFormedResponse(packet, 32210b57cec5SDimitry Andric "qXfer packet missing comma after offset"); 32220b57cec5SDimitry Andric // Parse out the length. 32230b57cec5SDimitry Andric const uint64_t xfer_length = 32240b57cec5SDimitry Andric offset_data.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max()); 32250b57cec5SDimitry Andric if (xfer_length == std::numeric_limits<uint64_t>::max()) 32260b57cec5SDimitry Andric return SendIllFormedResponse(packet, "qXfer packet missing length"); 32270b57cec5SDimitry Andric 32280b57cec5SDimitry Andric // Get a previously constructed buffer if it exists or create it now. 32290b57cec5SDimitry Andric std::string buffer_key = (xfer_object + xfer_action + xfer_annex).str(); 32300b57cec5SDimitry Andric auto buffer_it = m_xfer_buffer_map.find(buffer_key); 32310b57cec5SDimitry Andric if (buffer_it == m_xfer_buffer_map.end()) { 32320b57cec5SDimitry Andric auto buffer_up = ReadXferObject(xfer_object, xfer_annex); 32330b57cec5SDimitry Andric if (!buffer_up) 32340b57cec5SDimitry Andric return SendErrorResponse(buffer_up.takeError()); 32350b57cec5SDimitry Andric buffer_it = m_xfer_buffer_map 32360b57cec5SDimitry Andric .insert(std::make_pair(buffer_key, std::move(*buffer_up))) 32370b57cec5SDimitry Andric .first; 32380b57cec5SDimitry Andric } 32390b57cec5SDimitry Andric 32400b57cec5SDimitry Andric // Send back the response 32410b57cec5SDimitry Andric StreamGDBRemote response; 32420b57cec5SDimitry Andric bool done_with_buffer = false; 32430b57cec5SDimitry Andric llvm::StringRef buffer = buffer_it->second->getBuffer(); 32440b57cec5SDimitry Andric if (xfer_offset >= buffer.size()) { 32450b57cec5SDimitry Andric // We have nothing left to send. Mark the buffer as complete. 32460b57cec5SDimitry Andric response.PutChar('l'); 32470b57cec5SDimitry Andric done_with_buffer = true; 32480b57cec5SDimitry Andric } else { 32490b57cec5SDimitry Andric // Figure out how many bytes are available starting at the given offset. 32500b57cec5SDimitry Andric buffer = buffer.drop_front(xfer_offset); 32510b57cec5SDimitry Andric // Mark the response type according to whether we're reading the remainder 32520b57cec5SDimitry Andric // of the data. 32530b57cec5SDimitry Andric if (xfer_length >= buffer.size()) { 32540b57cec5SDimitry Andric // There will be nothing left to read after this 32550b57cec5SDimitry Andric response.PutChar('l'); 32560b57cec5SDimitry Andric done_with_buffer = true; 32570b57cec5SDimitry Andric } else { 32580b57cec5SDimitry Andric // There will still be bytes to read after this request. 32590b57cec5SDimitry Andric response.PutChar('m'); 32600b57cec5SDimitry Andric buffer = buffer.take_front(xfer_length); 32610b57cec5SDimitry Andric } 32620b57cec5SDimitry Andric // Now write the data in encoded binary form. 32630b57cec5SDimitry Andric response.PutEscapedBytes(buffer.data(), buffer.size()); 32640b57cec5SDimitry Andric } 32650b57cec5SDimitry Andric 32660b57cec5SDimitry Andric if (done_with_buffer) 32670b57cec5SDimitry Andric m_xfer_buffer_map.erase(buffer_it); 32680b57cec5SDimitry Andric 32690b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 32700b57cec5SDimitry Andric } 32710b57cec5SDimitry Andric 32720b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 32730b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( 32740b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 327581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 32760b57cec5SDimitry Andric 32770b57cec5SDimitry Andric // Move past packet name. 32780b57cec5SDimitry Andric packet.SetFilePos(strlen("QSaveRegisterState")); 32790b57cec5SDimitry Andric 32800b57cec5SDimitry Andric // Get the thread to use. 32810b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 32820b57cec5SDimitry Andric if (!thread) { 32830b57cec5SDimitry Andric if (m_thread_suffix_supported) 32840b57cec5SDimitry Andric return SendIllFormedResponse( 32850b57cec5SDimitry Andric packet, "No thread specified in QSaveRegisterState packet"); 32860b57cec5SDimitry Andric else 32870b57cec5SDimitry Andric return SendIllFormedResponse(packet, 32880b57cec5SDimitry Andric "No thread was is set with the Hg packet"); 32890b57cec5SDimitry Andric } 32900b57cec5SDimitry Andric 32910b57cec5SDimitry Andric // Grab the register context for the thread. 32920b57cec5SDimitry Andric NativeRegisterContext& reg_context = thread->GetRegisterContext(); 32930b57cec5SDimitry Andric 32940b57cec5SDimitry Andric // Save registers to a buffer. 329581ad6265SDimitry Andric WritableDataBufferSP register_data_sp; 32960b57cec5SDimitry Andric Status error = reg_context.ReadAllRegisterValues(register_data_sp); 32970b57cec5SDimitry Andric if (error.Fail()) { 32980b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to save all register values: {1}", 3299fe6060f1SDimitry Andric m_current_process->GetID(), error); 33000b57cec5SDimitry Andric return SendErrorResponse(0x75); 33010b57cec5SDimitry Andric } 33020b57cec5SDimitry Andric 33030b57cec5SDimitry Andric // Allocate a new save id. 33040b57cec5SDimitry Andric const uint32_t save_id = GetNextSavedRegistersID(); 33050b57cec5SDimitry Andric assert((m_saved_registers_map.find(save_id) == m_saved_registers_map.end()) && 33060b57cec5SDimitry Andric "GetNextRegisterSaveID() returned an existing register save id"); 33070b57cec5SDimitry Andric 33080b57cec5SDimitry Andric // Save the register data buffer under the save id. 33090b57cec5SDimitry Andric { 33100b57cec5SDimitry Andric std::lock_guard<std::mutex> guard(m_saved_registers_mutex); 33110b57cec5SDimitry Andric m_saved_registers_map[save_id] = register_data_sp; 33120b57cec5SDimitry Andric } 33130b57cec5SDimitry Andric 33140b57cec5SDimitry Andric // Write the response. 33150b57cec5SDimitry Andric StreamGDBRemote response; 33160b57cec5SDimitry Andric response.Printf("%" PRIu32, save_id); 33170b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 33180b57cec5SDimitry Andric } 33190b57cec5SDimitry Andric 33200b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 33210b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( 33220b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 332381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 33240b57cec5SDimitry Andric 33250b57cec5SDimitry Andric // Parse out save id. 33260b57cec5SDimitry Andric packet.SetFilePos(strlen("QRestoreRegisterState:")); 33270b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 33280b57cec5SDimitry Andric return SendIllFormedResponse( 33290b57cec5SDimitry Andric packet, "QRestoreRegisterState packet missing register save id"); 33300b57cec5SDimitry Andric 33310b57cec5SDimitry Andric const uint32_t save_id = packet.GetU32(0); 33320b57cec5SDimitry Andric if (save_id == 0) { 33330b57cec5SDimitry Andric LLDB_LOG(log, "QRestoreRegisterState packet has malformed save id, " 33340b57cec5SDimitry Andric "expecting decimal uint32_t"); 33350b57cec5SDimitry Andric return SendErrorResponse(0x76); 33360b57cec5SDimitry Andric } 33370b57cec5SDimitry Andric 33380b57cec5SDimitry Andric // Get the thread to use. 33390b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 33400b57cec5SDimitry Andric if (!thread) { 33410b57cec5SDimitry Andric if (m_thread_suffix_supported) 33420b57cec5SDimitry Andric return SendIllFormedResponse( 33430b57cec5SDimitry Andric packet, "No thread specified in QRestoreRegisterState packet"); 33440b57cec5SDimitry Andric else 33450b57cec5SDimitry Andric return SendIllFormedResponse(packet, 33460b57cec5SDimitry Andric "No thread was is set with the Hg packet"); 33470b57cec5SDimitry Andric } 33480b57cec5SDimitry Andric 33490b57cec5SDimitry Andric // Grab the register context for the thread. 33500b57cec5SDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 33510b57cec5SDimitry Andric 33520b57cec5SDimitry Andric // Retrieve register state buffer, then remove from the list. 33530b57cec5SDimitry Andric DataBufferSP register_data_sp; 33540b57cec5SDimitry Andric { 33550b57cec5SDimitry Andric std::lock_guard<std::mutex> guard(m_saved_registers_mutex); 33560b57cec5SDimitry Andric 33570b57cec5SDimitry Andric // Find the register set buffer for the given save id. 33580b57cec5SDimitry Andric auto it = m_saved_registers_map.find(save_id); 33590b57cec5SDimitry Andric if (it == m_saved_registers_map.end()) { 33600b57cec5SDimitry Andric LLDB_LOG(log, 33610b57cec5SDimitry Andric "pid {0} does not have a register set save buffer for id {1}", 3362fe6060f1SDimitry Andric m_current_process->GetID(), save_id); 33630b57cec5SDimitry Andric return SendErrorResponse(0x77); 33640b57cec5SDimitry Andric } 33650b57cec5SDimitry Andric register_data_sp = it->second; 33660b57cec5SDimitry Andric 33670b57cec5SDimitry Andric // Remove it from the map. 33680b57cec5SDimitry Andric m_saved_registers_map.erase(it); 33690b57cec5SDimitry Andric } 33700b57cec5SDimitry Andric 33710b57cec5SDimitry Andric Status error = reg_context.WriteAllRegisterValues(register_data_sp); 33720b57cec5SDimitry Andric if (error.Fail()) { 33730b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to restore all register values: {1}", 3374fe6060f1SDimitry Andric m_current_process->GetID(), error); 33750b57cec5SDimitry Andric return SendErrorResponse(0x77); 33760b57cec5SDimitry Andric } 33770b57cec5SDimitry Andric 33780b57cec5SDimitry Andric return SendOKResponse(); 33790b57cec5SDimitry Andric } 33800b57cec5SDimitry Andric 33810b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 33820b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vAttach( 33830b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 338481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 33850b57cec5SDimitry Andric 33860b57cec5SDimitry Andric // Consume the ';' after vAttach. 33870b57cec5SDimitry Andric packet.SetFilePos(strlen("vAttach")); 33880b57cec5SDimitry Andric if (!packet.GetBytesLeft() || packet.GetChar() != ';') 33890b57cec5SDimitry Andric return SendIllFormedResponse(packet, "vAttach missing expected ';'"); 33900b57cec5SDimitry Andric 33910b57cec5SDimitry Andric // Grab the PID to which we will attach (assume hex encoding). 33920b57cec5SDimitry Andric lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); 33930b57cec5SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 33940b57cec5SDimitry Andric return SendIllFormedResponse(packet, 33950b57cec5SDimitry Andric "vAttach failed to parse the process id"); 33960b57cec5SDimitry Andric 33970b57cec5SDimitry Andric // Attempt to attach. 33989dba64beSDimitry Andric LLDB_LOGF(log, 33999dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s attempting to attach to " 34000b57cec5SDimitry Andric "pid %" PRIu64, 34010b57cec5SDimitry Andric __FUNCTION__, pid); 34020b57cec5SDimitry Andric 34030b57cec5SDimitry Andric Status error = AttachToProcess(pid); 34040b57cec5SDimitry Andric 34050b57cec5SDimitry Andric if (error.Fail()) { 34069dba64beSDimitry Andric LLDB_LOGF(log, 34079dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to attach to " 34080b57cec5SDimitry Andric "pid %" PRIu64 ": %s\n", 34090b57cec5SDimitry Andric __FUNCTION__, pid, error.AsCString()); 34100b57cec5SDimitry Andric return SendErrorResponse(error); 34110b57cec5SDimitry Andric } 34120b57cec5SDimitry Andric 34130b57cec5SDimitry Andric // Notify we attached by sending a stop packet. 341481ad6265SDimitry Andric assert(m_current_process); 341581ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 341681ad6265SDimitry Andric m_current_process->GetState(), 341781ad6265SDimitry Andric /*force_synchronous=*/false); 34180b57cec5SDimitry Andric } 34190b57cec5SDimitry Andric 34200b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 3421e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vAttachWait( 3422e8d8bef9SDimitry Andric StringExtractorGDBRemote &packet) { 342381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3424e8d8bef9SDimitry Andric 3425e8d8bef9SDimitry Andric // Consume the ';' after the identifier. 3426e8d8bef9SDimitry Andric packet.SetFilePos(strlen("vAttachWait")); 3427e8d8bef9SDimitry Andric 3428e8d8bef9SDimitry Andric if (!packet.GetBytesLeft() || packet.GetChar() != ';') 3429e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "vAttachWait missing expected ';'"); 3430e8d8bef9SDimitry Andric 3431e8d8bef9SDimitry Andric // Allocate the buffer for the process name from vAttachWait. 3432e8d8bef9SDimitry Andric std::string process_name; 3433e8d8bef9SDimitry Andric if (!packet.GetHexByteString(process_name)) 3434e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, 3435e8d8bef9SDimitry Andric "vAttachWait failed to parse process name"); 3436e8d8bef9SDimitry Andric 3437e8d8bef9SDimitry Andric LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name); 3438e8d8bef9SDimitry Andric 3439e8d8bef9SDimitry Andric Status error = AttachWaitProcess(process_name, false); 3440e8d8bef9SDimitry Andric if (error.Fail()) { 3441e8d8bef9SDimitry Andric LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name, 3442e8d8bef9SDimitry Andric error); 3443e8d8bef9SDimitry Andric return SendErrorResponse(error); 3444e8d8bef9SDimitry Andric } 3445e8d8bef9SDimitry Andric 3446e8d8bef9SDimitry Andric // Notify we attached by sending a stop packet. 344781ad6265SDimitry Andric assert(m_current_process); 344881ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 344981ad6265SDimitry Andric m_current_process->GetState(), 345081ad6265SDimitry Andric /*force_synchronous=*/false); 3451e8d8bef9SDimitry Andric } 3452e8d8bef9SDimitry Andric 3453e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 3454e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported( 3455e8d8bef9SDimitry Andric StringExtractorGDBRemote &packet) { 3456e8d8bef9SDimitry Andric return SendOKResponse(); 3457e8d8bef9SDimitry Andric } 3458e8d8bef9SDimitry Andric 3459e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 3460e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait( 3461e8d8bef9SDimitry Andric StringExtractorGDBRemote &packet) { 346281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3463e8d8bef9SDimitry Andric 3464e8d8bef9SDimitry Andric // Consume the ';' after the identifier. 3465e8d8bef9SDimitry Andric packet.SetFilePos(strlen("vAttachOrWait")); 3466e8d8bef9SDimitry Andric 3467e8d8bef9SDimitry Andric if (!packet.GetBytesLeft() || packet.GetChar() != ';') 3468e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "vAttachOrWait missing expected ';'"); 3469e8d8bef9SDimitry Andric 3470e8d8bef9SDimitry Andric // Allocate the buffer for the process name from vAttachWait. 3471e8d8bef9SDimitry Andric std::string process_name; 3472e8d8bef9SDimitry Andric if (!packet.GetHexByteString(process_name)) 3473e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, 3474e8d8bef9SDimitry Andric "vAttachOrWait failed to parse process name"); 3475e8d8bef9SDimitry Andric 3476e8d8bef9SDimitry Andric LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name); 3477e8d8bef9SDimitry Andric 3478e8d8bef9SDimitry Andric Status error = AttachWaitProcess(process_name, true); 3479e8d8bef9SDimitry Andric if (error.Fail()) { 3480e8d8bef9SDimitry Andric LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name, 3481e8d8bef9SDimitry Andric error); 3482e8d8bef9SDimitry Andric return SendErrorResponse(error); 3483e8d8bef9SDimitry Andric } 3484e8d8bef9SDimitry Andric 3485e8d8bef9SDimitry Andric // Notify we attached by sending a stop packet. 348681ad6265SDimitry Andric assert(m_current_process); 348781ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 348881ad6265SDimitry Andric m_current_process->GetState(), 348981ad6265SDimitry Andric /*force_synchronous=*/false); 3490e8d8bef9SDimitry Andric } 3491e8d8bef9SDimitry Andric 3492e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 3493349cc55cSDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vRun( 3494349cc55cSDimitry Andric StringExtractorGDBRemote &packet) { 349581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3496349cc55cSDimitry Andric 3497349cc55cSDimitry Andric llvm::StringRef s = packet.GetStringRef(); 3498349cc55cSDimitry Andric if (!s.consume_front("vRun;")) 3499349cc55cSDimitry Andric return SendErrorResponse(8); 3500349cc55cSDimitry Andric 3501349cc55cSDimitry Andric llvm::SmallVector<llvm::StringRef, 16> argv; 3502349cc55cSDimitry Andric s.split(argv, ';'); 3503349cc55cSDimitry Andric 3504349cc55cSDimitry Andric for (llvm::StringRef hex_arg : argv) { 3505349cc55cSDimitry Andric StringExtractor arg_ext{hex_arg}; 3506349cc55cSDimitry Andric std::string arg; 3507349cc55cSDimitry Andric arg_ext.GetHexByteString(arg); 3508349cc55cSDimitry Andric m_process_launch_info.GetArguments().AppendArgument(arg); 3509349cc55cSDimitry Andric LLDB_LOGF(log, "LLGSPacketHandler::%s added arg: \"%s\"", __FUNCTION__, 3510349cc55cSDimitry Andric arg.c_str()); 3511349cc55cSDimitry Andric } 3512349cc55cSDimitry Andric 3513349cc55cSDimitry Andric if (!argv.empty()) { 3514349cc55cSDimitry Andric m_process_launch_info.GetExecutableFile().SetFile( 3515349cc55cSDimitry Andric m_process_launch_info.GetArguments()[0].ref(), FileSpec::Style::native); 3516349cc55cSDimitry Andric m_process_launch_error = LaunchProcess(); 351781ad6265SDimitry Andric if (m_process_launch_error.Success()) { 351881ad6265SDimitry Andric assert(m_current_process); 351981ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 352081ad6265SDimitry Andric m_current_process->GetState(), 352181ad6265SDimitry Andric /*force_synchronous=*/true); 352281ad6265SDimitry Andric } 3523349cc55cSDimitry Andric LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error); 3524349cc55cSDimitry Andric } 3525349cc55cSDimitry Andric return SendErrorResponse(8); 3526349cc55cSDimitry Andric } 3527349cc55cSDimitry Andric 3528349cc55cSDimitry Andric GDBRemoteCommunication::PacketResult 35290b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { 353081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3531fcaf7f86SDimitry Andric if (!m_non_stop) 35320b57cec5SDimitry Andric StopSTDIOForwarding(); 35330b57cec5SDimitry Andric 35340b57cec5SDimitry Andric lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 35350b57cec5SDimitry Andric 35360b57cec5SDimitry Andric // Consume the ';' after D. 35370b57cec5SDimitry Andric packet.SetFilePos(1); 35380b57cec5SDimitry Andric if (packet.GetBytesLeft()) { 35390b57cec5SDimitry Andric if (packet.GetChar() != ';') 35400b57cec5SDimitry Andric return SendIllFormedResponse(packet, "D missing expected ';'"); 35410b57cec5SDimitry Andric 35420b57cec5SDimitry Andric // Grab the PID from which we will detach (assume hex encoding). 35430b57cec5SDimitry Andric pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); 35440b57cec5SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 35450b57cec5SDimitry Andric return SendIllFormedResponse(packet, "D failed to parse the process id"); 35460b57cec5SDimitry Andric } 35470b57cec5SDimitry Andric 3548fe6060f1SDimitry Andric // Detach forked children if their PID was specified *or* no PID was requested 3549fe6060f1SDimitry Andric // (i.e. detach-all packet). 3550fe6060f1SDimitry Andric llvm::Error detach_error = llvm::Error::success(); 3551fe6060f1SDimitry Andric bool detached = false; 3552fe6060f1SDimitry Andric for (auto it = m_debugged_processes.begin(); 3553fe6060f1SDimitry Andric it != m_debugged_processes.end();) { 3554fe6060f1SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID || pid == it->first) { 355581ad6265SDimitry Andric LLDB_LOGF(log, 355681ad6265SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s detaching %" PRId64, 355781ad6265SDimitry Andric __FUNCTION__, it->first); 3558fcaf7f86SDimitry Andric if (llvm::Error e = it->second.process_up->Detach().ToError()) 3559fe6060f1SDimitry Andric detach_error = llvm::joinErrors(std::move(detach_error), std::move(e)); 3560fe6060f1SDimitry Andric else { 3561fcaf7f86SDimitry Andric if (it->second.process_up.get() == m_current_process) 3562fe6060f1SDimitry Andric m_current_process = nullptr; 3563fcaf7f86SDimitry Andric if (it->second.process_up.get() == m_continue_process) 3564fe6060f1SDimitry Andric m_continue_process = nullptr; 3565fe6060f1SDimitry Andric it = m_debugged_processes.erase(it); 3566fe6060f1SDimitry Andric detached = true; 3567fe6060f1SDimitry Andric continue; 3568fe6060f1SDimitry Andric } 3569fe6060f1SDimitry Andric } 3570fe6060f1SDimitry Andric ++it; 35710b57cec5SDimitry Andric } 35720b57cec5SDimitry Andric 3573fe6060f1SDimitry Andric if (detach_error) 3574fe6060f1SDimitry Andric return SendErrorResponse(std::move(detach_error)); 3575fe6060f1SDimitry Andric if (!detached) 3576fe6060f1SDimitry Andric return SendErrorResponse(Status("PID %" PRIu64 " not traced", pid)); 35770b57cec5SDimitry Andric return SendOKResponse(); 35780b57cec5SDimitry Andric } 35790b57cec5SDimitry Andric 35800b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 35810b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo( 35820b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 358381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 358481ad6265SDimitry Andric 358581ad6265SDimitry Andric if (!m_current_process || 358681ad6265SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 358781ad6265SDimitry Andric return SendErrorResponse(50); 35880b57cec5SDimitry Andric 35890b57cec5SDimitry Andric packet.SetFilePos(strlen("qThreadStopInfo")); 3590fe6060f1SDimitry Andric const lldb::tid_t tid = packet.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID); 35910b57cec5SDimitry Andric if (tid == LLDB_INVALID_THREAD_ID) { 35929dba64beSDimitry Andric LLDB_LOGF(log, 35939dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, could not " 35940b57cec5SDimitry Andric "parse thread id from request \"%s\"", 35959dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 35960b57cec5SDimitry Andric return SendErrorResponse(0x15); 35970b57cec5SDimitry Andric } 359881ad6265SDimitry Andric return SendStopReplyPacketForThread(*m_current_process, tid, 359981ad6265SDimitry Andric /*force_synchronous=*/true); 36000b57cec5SDimitry Andric } 36010b57cec5SDimitry Andric 36020b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 36030b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo( 36040b57cec5SDimitry Andric StringExtractorGDBRemote &) { 360581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 36060b57cec5SDimitry Andric 36070b57cec5SDimitry Andric // Ensure we have a debugged process. 3608fe6060f1SDimitry Andric if (!m_current_process || 3609fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 36100b57cec5SDimitry Andric return SendErrorResponse(50); 3611fe6060f1SDimitry Andric LLDB_LOG(log, "preparing packet for pid {0}", m_current_process->GetID()); 36120b57cec5SDimitry Andric 36130b57cec5SDimitry Andric StreamString response; 36140b57cec5SDimitry Andric const bool threads_with_valid_stop_info_only = false; 3615fe6060f1SDimitry Andric llvm::Expected<json::Value> threads_info = 3616fe6060f1SDimitry Andric GetJSONThreadsInfo(*m_current_process, threads_with_valid_stop_info_only); 36179dba64beSDimitry Andric if (!threads_info) { 3618480093f4SDimitry Andric LLDB_LOG_ERROR(log, threads_info.takeError(), 3619480093f4SDimitry Andric "failed to prepare a packet for pid {1}: {0}", 3620fe6060f1SDimitry Andric m_current_process->GetID()); 36210b57cec5SDimitry Andric return SendErrorResponse(52); 36220b57cec5SDimitry Andric } 36230b57cec5SDimitry Andric 36249dba64beSDimitry Andric response.AsRawOstream() << *threads_info; 36250b57cec5SDimitry Andric StreamGDBRemote escaped_response; 36260b57cec5SDimitry Andric escaped_response.PutEscapedBytes(response.GetData(), response.GetSize()); 36270b57cec5SDimitry Andric return SendPacketNoLock(escaped_response.GetString()); 36280b57cec5SDimitry Andric } 36290b57cec5SDimitry Andric 36300b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 36310b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo( 36320b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 36330b57cec5SDimitry Andric // Fail if we don't have a current process. 3634fe6060f1SDimitry Andric if (!m_current_process || 3635fe6060f1SDimitry Andric m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) 36360b57cec5SDimitry Andric return SendErrorResponse(68); 36370b57cec5SDimitry Andric 36380b57cec5SDimitry Andric packet.SetFilePos(strlen("qWatchpointSupportInfo")); 36390b57cec5SDimitry Andric if (packet.GetBytesLeft() == 0) 36400b57cec5SDimitry Andric return SendOKResponse(); 36410b57cec5SDimitry Andric if (packet.GetChar() != ':') 36420b57cec5SDimitry Andric return SendErrorResponse(67); 36430b57cec5SDimitry Andric 3644fe6060f1SDimitry Andric auto hw_debug_cap = m_current_process->GetHardwareDebugSupportInfo(); 36450b57cec5SDimitry Andric 36460b57cec5SDimitry Andric StreamGDBRemote response; 36470b57cec5SDimitry Andric if (hw_debug_cap == llvm::None) 36480b57cec5SDimitry Andric response.Printf("num:0;"); 36490b57cec5SDimitry Andric else 36500b57cec5SDimitry Andric response.Printf("num:%d;", hw_debug_cap->second); 36510b57cec5SDimitry Andric 36520b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 36530b57cec5SDimitry Andric } 36540b57cec5SDimitry Andric 36550b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 36560b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress( 36570b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 36580b57cec5SDimitry Andric // Fail if we don't have a current process. 3659fe6060f1SDimitry Andric if (!m_current_process || 3660fe6060f1SDimitry Andric m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) 36610b57cec5SDimitry Andric return SendErrorResponse(67); 36620b57cec5SDimitry Andric 36630b57cec5SDimitry Andric packet.SetFilePos(strlen("qFileLoadAddress:")); 36640b57cec5SDimitry Andric if (packet.GetBytesLeft() == 0) 36650b57cec5SDimitry Andric return SendErrorResponse(68); 36660b57cec5SDimitry Andric 36670b57cec5SDimitry Andric std::string file_name; 36680b57cec5SDimitry Andric packet.GetHexByteString(file_name); 36690b57cec5SDimitry Andric 36700b57cec5SDimitry Andric lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS; 36710b57cec5SDimitry Andric Status error = 3672fe6060f1SDimitry Andric m_current_process->GetFileLoadAddress(file_name, file_load_address); 36730b57cec5SDimitry Andric if (error.Fail()) 36740b57cec5SDimitry Andric return SendErrorResponse(69); 36750b57cec5SDimitry Andric 36760b57cec5SDimitry Andric if (file_load_address == LLDB_INVALID_ADDRESS) 36770b57cec5SDimitry Andric return SendErrorResponse(1); // File not loaded 36780b57cec5SDimitry Andric 36790b57cec5SDimitry Andric StreamGDBRemote response; 36800b57cec5SDimitry Andric response.PutHex64(file_load_address); 36810b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 36820b57cec5SDimitry Andric } 36830b57cec5SDimitry Andric 36840b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 36850b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QPassSignals( 36860b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 36870b57cec5SDimitry Andric std::vector<int> signals; 36880b57cec5SDimitry Andric packet.SetFilePos(strlen("QPassSignals:")); 36890b57cec5SDimitry Andric 36900b57cec5SDimitry Andric // Read sequence of hex signal numbers divided by a semicolon and optionally 36910b57cec5SDimitry Andric // spaces. 36920b57cec5SDimitry Andric while (packet.GetBytesLeft() > 0) { 36930b57cec5SDimitry Andric int signal = packet.GetS32(-1, 16); 36940b57cec5SDimitry Andric if (signal < 0) 36950b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Failed to parse signal number."); 36960b57cec5SDimitry Andric signals.push_back(signal); 36970b57cec5SDimitry Andric 36980b57cec5SDimitry Andric packet.SkipSpaces(); 36990b57cec5SDimitry Andric char separator = packet.GetChar(); 37000b57cec5SDimitry Andric if (separator == '\0') 37010b57cec5SDimitry Andric break; // End of string 37020b57cec5SDimitry Andric if (separator != ';') 37030b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Invalid separator," 37040b57cec5SDimitry Andric " expected semicolon."); 37050b57cec5SDimitry Andric } 37060b57cec5SDimitry Andric 37070b57cec5SDimitry Andric // Fail if we don't have a current process. 3708fe6060f1SDimitry Andric if (!m_current_process) 37090b57cec5SDimitry Andric return SendErrorResponse(68); 37100b57cec5SDimitry Andric 3711fe6060f1SDimitry Andric Status error = m_current_process->IgnoreSignals(signals); 37120b57cec5SDimitry Andric if (error.Fail()) 37130b57cec5SDimitry Andric return SendErrorResponse(69); 37140b57cec5SDimitry Andric 37150b57cec5SDimitry Andric return SendOKResponse(); 37160b57cec5SDimitry Andric } 37170b57cec5SDimitry Andric 3718fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult 3719fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qMemTags( 3720fe6060f1SDimitry Andric StringExtractorGDBRemote &packet) { 372181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3722fe6060f1SDimitry Andric 3723fe6060f1SDimitry Andric // Ensure we have a process. 3724fe6060f1SDimitry Andric if (!m_current_process || 3725fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 3726fe6060f1SDimitry Andric LLDB_LOGF( 3727fe6060f1SDimitry Andric log, 3728fe6060f1SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 3729fe6060f1SDimitry Andric __FUNCTION__); 3730fe6060f1SDimitry Andric return SendErrorResponse(1); 3731fe6060f1SDimitry Andric } 3732fe6060f1SDimitry Andric 3733fe6060f1SDimitry Andric // We are expecting 3734fe6060f1SDimitry Andric // qMemTags:<hex address>,<hex length>:<hex type> 3735fe6060f1SDimitry Andric 3736fe6060f1SDimitry Andric // Address 3737fe6060f1SDimitry Andric packet.SetFilePos(strlen("qMemTags:")); 3738fe6060f1SDimitry Andric const char *current_char = packet.Peek(); 3739fe6060f1SDimitry Andric if (!current_char || *current_char == ',') 3740fe6060f1SDimitry Andric return SendIllFormedResponse(packet, "Missing address in qMemTags packet"); 3741fe6060f1SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0); 3742fe6060f1SDimitry Andric 3743fe6060f1SDimitry Andric // Length 3744fe6060f1SDimitry Andric char previous_char = packet.GetChar(); 3745fe6060f1SDimitry Andric current_char = packet.Peek(); 3746fe6060f1SDimitry Andric // If we don't have a separator or the length field is empty 3747fe6060f1SDimitry Andric if (previous_char != ',' || (current_char && *current_char == ':')) 3748fe6060f1SDimitry Andric return SendIllFormedResponse(packet, 3749fe6060f1SDimitry Andric "Invalid addr,length pair in qMemTags packet"); 3750fe6060f1SDimitry Andric 3751fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1) 3752fe6060f1SDimitry Andric return SendIllFormedResponse( 3753fe6060f1SDimitry Andric packet, "Too short qMemtags: packet (looking for length)"); 3754fe6060f1SDimitry Andric const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0); 3755fe6060f1SDimitry Andric 3756fe6060f1SDimitry Andric // Type 3757fe6060f1SDimitry Andric const char *invalid_type_err = "Invalid type field in qMemTags: packet"; 3758fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') 3759fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 3760fe6060f1SDimitry Andric 37616e75b2fbSDimitry Andric // Type is a signed integer but packed into the packet as its raw bytes. 37626e75b2fbSDimitry Andric // However, our GetU64 uses strtoull which allows +/-. We do not want this. 37636e75b2fbSDimitry Andric const char *first_type_char = packet.Peek(); 37646e75b2fbSDimitry Andric if (first_type_char && (*first_type_char == '+' || *first_type_char == '-')) 37656e75b2fbSDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 37666e75b2fbSDimitry Andric 37676e75b2fbSDimitry Andric // Extract type as unsigned then cast to signed. 37686e75b2fbSDimitry Andric // Using a uint64_t here so that we have some value outside of the 32 bit 37696e75b2fbSDimitry Andric // range to use as the invalid return value. 37706e75b2fbSDimitry Andric uint64_t raw_type = 37716e75b2fbSDimitry Andric packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16); 37726e75b2fbSDimitry Andric 37736e75b2fbSDimitry Andric if ( // Make sure the cast below would be valid 37746e75b2fbSDimitry Andric raw_type > std::numeric_limits<uint32_t>::max() || 3775fe6060f1SDimitry Andric // To catch inputs like "123aardvark" that will parse but clearly aren't 3776fe6060f1SDimitry Andric // valid in this case. 3777fe6060f1SDimitry Andric packet.GetBytesLeft()) { 3778fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 3779fe6060f1SDimitry Andric } 3780fe6060f1SDimitry Andric 37816e75b2fbSDimitry Andric // First narrow to 32 bits otherwise the copy into type would take 37826e75b2fbSDimitry Andric // the wrong 4 bytes on big endian. 37836e75b2fbSDimitry Andric uint32_t raw_type_32 = raw_type; 37846e75b2fbSDimitry Andric int32_t type = reinterpret_cast<int32_t &>(raw_type_32); 37856e75b2fbSDimitry Andric 3786fe6060f1SDimitry Andric StreamGDBRemote response; 3787fe6060f1SDimitry Andric std::vector<uint8_t> tags; 3788fe6060f1SDimitry Andric Status error = m_current_process->ReadMemoryTags(type, addr, length, tags); 3789fe6060f1SDimitry Andric if (error.Fail()) 3790fe6060f1SDimitry Andric return SendErrorResponse(1); 3791fe6060f1SDimitry Andric 3792fe6060f1SDimitry Andric // This m is here in case we want to support multi part replies in the future. 3793fe6060f1SDimitry Andric // In the same manner as qfThreadInfo/qsThreadInfo. 3794fe6060f1SDimitry Andric response.PutChar('m'); 3795fe6060f1SDimitry Andric response.PutBytesAsRawHex8(tags.data(), tags.size()); 3796fe6060f1SDimitry Andric return SendPacketNoLock(response.GetString()); 3797fe6060f1SDimitry Andric } 3798fe6060f1SDimitry Andric 3799fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult 3800fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QMemTags( 3801fe6060f1SDimitry Andric StringExtractorGDBRemote &packet) { 380281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3803fe6060f1SDimitry Andric 3804fe6060f1SDimitry Andric // Ensure we have a process. 3805fe6060f1SDimitry Andric if (!m_current_process || 3806fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 3807fe6060f1SDimitry Andric LLDB_LOGF( 3808fe6060f1SDimitry Andric log, 3809fe6060f1SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 3810fe6060f1SDimitry Andric __FUNCTION__); 3811fe6060f1SDimitry Andric return SendErrorResponse(1); 3812fe6060f1SDimitry Andric } 3813fe6060f1SDimitry Andric 3814fe6060f1SDimitry Andric // We are expecting 3815fe6060f1SDimitry Andric // QMemTags:<hex address>,<hex length>:<hex type>:<tags as hex bytes> 3816fe6060f1SDimitry Andric 3817fe6060f1SDimitry Andric // Address 3818fe6060f1SDimitry Andric packet.SetFilePos(strlen("QMemTags:")); 3819fe6060f1SDimitry Andric const char *current_char = packet.Peek(); 3820fe6060f1SDimitry Andric if (!current_char || *current_char == ',') 3821fe6060f1SDimitry Andric return SendIllFormedResponse(packet, "Missing address in QMemTags packet"); 3822fe6060f1SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0); 3823fe6060f1SDimitry Andric 3824fe6060f1SDimitry Andric // Length 3825fe6060f1SDimitry Andric char previous_char = packet.GetChar(); 3826fe6060f1SDimitry Andric current_char = packet.Peek(); 3827fe6060f1SDimitry Andric // If we don't have a separator or the length field is empty 3828fe6060f1SDimitry Andric if (previous_char != ',' || (current_char && *current_char == ':')) 3829fe6060f1SDimitry Andric return SendIllFormedResponse(packet, 3830fe6060f1SDimitry Andric "Invalid addr,length pair in QMemTags packet"); 3831fe6060f1SDimitry Andric 3832fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1) 3833fe6060f1SDimitry Andric return SendIllFormedResponse( 3834fe6060f1SDimitry Andric packet, "Too short QMemtags: packet (looking for length)"); 3835fe6060f1SDimitry Andric const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0); 3836fe6060f1SDimitry Andric 3837fe6060f1SDimitry Andric // Type 3838fe6060f1SDimitry Andric const char *invalid_type_err = "Invalid type field in QMemTags: packet"; 3839fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') 3840fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 3841fe6060f1SDimitry Andric 3842fe6060f1SDimitry Andric // Our GetU64 uses strtoull which allows leading +/-, we don't want that. 3843fe6060f1SDimitry Andric const char *first_type_char = packet.Peek(); 3844fe6060f1SDimitry Andric if (first_type_char && (*first_type_char == '+' || *first_type_char == '-')) 3845fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 3846fe6060f1SDimitry Andric 3847fe6060f1SDimitry Andric // The type is a signed integer but is in the packet as its raw bytes. 3848fe6060f1SDimitry Andric // So parse first as unsigned then cast to signed later. 3849fe6060f1SDimitry Andric // We extract to 64 bit, even though we only expect 32, so that we've 3850fe6060f1SDimitry Andric // got some invalid value we can check for. 3851fe6060f1SDimitry Andric uint64_t raw_type = 3852fe6060f1SDimitry Andric packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16); 3853fe6060f1SDimitry Andric if (raw_type > std::numeric_limits<uint32_t>::max()) 3854fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 38556e75b2fbSDimitry Andric 38566e75b2fbSDimitry Andric // First narrow to 32 bits. Otherwise the copy below would get the wrong 38576e75b2fbSDimitry Andric // 4 bytes on big endian. 38586e75b2fbSDimitry Andric uint32_t raw_type_32 = raw_type; 38596e75b2fbSDimitry Andric int32_t type = reinterpret_cast<int32_t &>(raw_type_32); 3860fe6060f1SDimitry Andric 3861fe6060f1SDimitry Andric // Tag data 3862fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') 3863fe6060f1SDimitry Andric return SendIllFormedResponse(packet, 3864fe6060f1SDimitry Andric "Missing tag data in QMemTags: packet"); 3865fe6060f1SDimitry Andric 3866fe6060f1SDimitry Andric // Must be 2 chars per byte 3867fe6060f1SDimitry Andric const char *invalid_data_err = "Invalid tag data in QMemTags: packet"; 3868fe6060f1SDimitry Andric if (packet.GetBytesLeft() % 2) 3869fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_data_err); 3870fe6060f1SDimitry Andric 3871fe6060f1SDimitry Andric // This is bytes here and is unpacked into target specific tags later 3872fe6060f1SDimitry Andric // We cannot assume that number of bytes == length here because the server 3873fe6060f1SDimitry Andric // can repeat tags to fill a given range. 3874fe6060f1SDimitry Andric std::vector<uint8_t> tag_data; 3875fe6060f1SDimitry Andric // Zero length writes will not have any tag data 3876fe6060f1SDimitry Andric // (but we pass them on because it will still check that tagging is enabled) 3877fe6060f1SDimitry Andric if (packet.GetBytesLeft()) { 3878fe6060f1SDimitry Andric size_t byte_count = packet.GetBytesLeft() / 2; 3879fe6060f1SDimitry Andric tag_data.resize(byte_count); 3880fe6060f1SDimitry Andric size_t converted_bytes = packet.GetHexBytes(tag_data, 0); 3881fe6060f1SDimitry Andric if (converted_bytes != byte_count) { 3882fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_data_err); 3883fe6060f1SDimitry Andric } 3884fe6060f1SDimitry Andric } 3885fe6060f1SDimitry Andric 3886fe6060f1SDimitry Andric Status status = 3887fe6060f1SDimitry Andric m_current_process->WriteMemoryTags(type, addr, length, tag_data); 3888fe6060f1SDimitry Andric return status.Success() ? SendOKResponse() : SendErrorResponse(1); 3889fe6060f1SDimitry Andric } 3890fe6060f1SDimitry Andric 3891349cc55cSDimitry Andric GDBRemoteCommunication::PacketResult 3892349cc55cSDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qSaveCore( 3893349cc55cSDimitry Andric StringExtractorGDBRemote &packet) { 3894349cc55cSDimitry Andric // Fail if we don't have a current process. 3895349cc55cSDimitry Andric if (!m_current_process || 3896349cc55cSDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 3897349cc55cSDimitry Andric return SendErrorResponse(Status("Process not running.")); 3898349cc55cSDimitry Andric 3899349cc55cSDimitry Andric std::string path_hint; 3900349cc55cSDimitry Andric 3901349cc55cSDimitry Andric StringRef packet_str{packet.GetStringRef()}; 3902349cc55cSDimitry Andric assert(packet_str.startswith("qSaveCore")); 3903349cc55cSDimitry Andric if (packet_str.consume_front("qSaveCore;")) { 3904349cc55cSDimitry Andric for (auto x : llvm::split(packet_str, ';')) { 3905349cc55cSDimitry Andric if (x.consume_front("path-hint:")) 3906349cc55cSDimitry Andric StringExtractor(x).GetHexByteString(path_hint); 3907349cc55cSDimitry Andric else 3908349cc55cSDimitry Andric return SendErrorResponse(Status("Unsupported qSaveCore option")); 3909349cc55cSDimitry Andric } 3910349cc55cSDimitry Andric } 3911349cc55cSDimitry Andric 3912349cc55cSDimitry Andric llvm::Expected<std::string> ret = m_current_process->SaveCore(path_hint); 3913349cc55cSDimitry Andric if (!ret) 3914349cc55cSDimitry Andric return SendErrorResponse(ret.takeError()); 3915349cc55cSDimitry Andric 3916349cc55cSDimitry Andric StreamString response; 3917349cc55cSDimitry Andric response.PutCString("core-path:"); 3918349cc55cSDimitry Andric response.PutStringAsRawHex8(ret.get()); 3919349cc55cSDimitry Andric return SendPacketNoLock(response.GetString()); 3920349cc55cSDimitry Andric } 3921349cc55cSDimitry Andric 392281ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 392381ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QNonStop( 392481ad6265SDimitry Andric StringExtractorGDBRemote &packet) { 3925fcaf7f86SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3926fcaf7f86SDimitry Andric 392781ad6265SDimitry Andric StringRef packet_str{packet.GetStringRef()}; 392881ad6265SDimitry Andric assert(packet_str.startswith("QNonStop:")); 392981ad6265SDimitry Andric packet_str.consume_front("QNonStop:"); 393081ad6265SDimitry Andric if (packet_str == "0") { 3931fcaf7f86SDimitry Andric if (m_non_stop) 3932fcaf7f86SDimitry Andric StopSTDIOForwarding(); 3933fcaf7f86SDimitry Andric for (auto &process_it : m_debugged_processes) { 3934fcaf7f86SDimitry Andric if (process_it.second.process_up->IsRunning()) { 3935fcaf7f86SDimitry Andric assert(m_non_stop); 3936fcaf7f86SDimitry Andric Status error = process_it.second.process_up->Interrupt(); 3937fcaf7f86SDimitry Andric if (error.Fail()) { 3938fcaf7f86SDimitry Andric LLDB_LOG(log, 3939fcaf7f86SDimitry Andric "while disabling nonstop, failed to halt process {0}: {1}", 3940fcaf7f86SDimitry Andric process_it.first, error); 3941fcaf7f86SDimitry Andric return SendErrorResponse(0x41); 3942fcaf7f86SDimitry Andric } 3943fcaf7f86SDimitry Andric // we must not send stop reasons after QNonStop 3944fcaf7f86SDimitry Andric m_disabling_non_stop = true; 3945fcaf7f86SDimitry Andric } 3946fcaf7f86SDimitry Andric } 3947fcaf7f86SDimitry Andric m_stdio_notification_queue.clear(); 3948fcaf7f86SDimitry Andric m_stop_notification_queue.clear(); 394981ad6265SDimitry Andric m_non_stop = false; 3950fcaf7f86SDimitry Andric // If we are stopping anything, defer sending the OK response until we're 3951fcaf7f86SDimitry Andric // done. 3952fcaf7f86SDimitry Andric if (m_disabling_non_stop) 3953fcaf7f86SDimitry Andric return PacketResult::Success; 395481ad6265SDimitry Andric } else if (packet_str == "1") { 3955fcaf7f86SDimitry Andric if (!m_non_stop) 3956fcaf7f86SDimitry Andric StartSTDIOForwarding(); 395781ad6265SDimitry Andric m_non_stop = true; 395881ad6265SDimitry Andric } else 395981ad6265SDimitry Andric return SendErrorResponse(Status("Invalid QNonStop packet")); 396081ad6265SDimitry Andric return SendOKResponse(); 396181ad6265SDimitry Andric } 396281ad6265SDimitry Andric 396381ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 3964fcaf7f86SDimitry Andric GDBRemoteCommunicationServerLLGS::HandleNotificationAck( 3965fcaf7f86SDimitry Andric std::deque<std::string> &queue) { 3966fcaf7f86SDimitry Andric // Per the protocol, the first message put into the queue is sent 3967fcaf7f86SDimitry Andric // immediately. However, it remains the queue until the client ACKs it -- 3968fcaf7f86SDimitry Andric // then we pop it and send the next message. The process repeats until 3969fcaf7f86SDimitry Andric // the last message in the queue is ACK-ed, in which case the packet sends 3970fcaf7f86SDimitry Andric // an OK response. 3971fcaf7f86SDimitry Andric if (queue.empty()) 3972fcaf7f86SDimitry Andric return SendErrorResponse(Status("No pending notification to ack")); 3973fcaf7f86SDimitry Andric queue.pop_front(); 3974fcaf7f86SDimitry Andric if (!queue.empty()) 3975fcaf7f86SDimitry Andric return SendPacketNoLock(queue.front()); 3976fcaf7f86SDimitry Andric return SendOKResponse(); 3977fcaf7f86SDimitry Andric } 3978fcaf7f86SDimitry Andric 3979fcaf7f86SDimitry Andric GDBRemoteCommunication::PacketResult 3980fcaf7f86SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vStdio( 3981fcaf7f86SDimitry Andric StringExtractorGDBRemote &packet) { 3982fcaf7f86SDimitry Andric return HandleNotificationAck(m_stdio_notification_queue); 3983fcaf7f86SDimitry Andric } 3984fcaf7f86SDimitry Andric 3985fcaf7f86SDimitry Andric GDBRemoteCommunication::PacketResult 398681ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vStopped( 398781ad6265SDimitry Andric StringExtractorGDBRemote &packet) { 3988fcaf7f86SDimitry Andric PacketResult ret = HandleNotificationAck(m_stop_notification_queue); 398981ad6265SDimitry Andric // If this was the last notification and all the processes exited, 399081ad6265SDimitry Andric // terminate the server. 3991fcaf7f86SDimitry Andric if (m_stop_notification_queue.empty() && m_debugged_processes.empty()) { 399281ad6265SDimitry Andric m_exit_now = true; 399381ad6265SDimitry Andric m_mainloop.RequestTermination(); 399481ad6265SDimitry Andric } 3995fcaf7f86SDimitry Andric return ret; 399681ad6265SDimitry Andric } 399781ad6265SDimitry Andric 399881ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 399981ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vCtrlC( 400081ad6265SDimitry Andric StringExtractorGDBRemote &packet) { 400181ad6265SDimitry Andric if (!m_non_stop) 400281ad6265SDimitry Andric return SendErrorResponse(Status("vCtrl is only valid in non-stop mode")); 400381ad6265SDimitry Andric 400481ad6265SDimitry Andric PacketResult interrupt_res = Handle_interrupt(packet); 400581ad6265SDimitry Andric // If interrupting the process failed, pass the result through. 400681ad6265SDimitry Andric if (interrupt_res != PacketResult::Success) 400781ad6265SDimitry Andric return interrupt_res; 400881ad6265SDimitry Andric // Otherwise, vCtrlC should issue an OK response (normal interrupts do not). 400981ad6265SDimitry Andric return SendOKResponse(); 401081ad6265SDimitry Andric } 401181ad6265SDimitry Andric 401281ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 401381ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_T(StringExtractorGDBRemote &packet) { 401481ad6265SDimitry Andric packet.SetFilePos(strlen("T")); 401581ad6265SDimitry Andric auto pid_tid = packet.GetPidTid(m_current_process ? m_current_process->GetID() 401681ad6265SDimitry Andric : LLDB_INVALID_PROCESS_ID); 401781ad6265SDimitry Andric if (!pid_tid) 401881ad6265SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 401981ad6265SDimitry Andric inconvertibleErrorCode(), "Malformed thread-id")); 402081ad6265SDimitry Andric 402181ad6265SDimitry Andric lldb::pid_t pid = pid_tid->first; 402281ad6265SDimitry Andric lldb::tid_t tid = pid_tid->second; 402381ad6265SDimitry Andric 402481ad6265SDimitry Andric // Technically, this would also be caught by the PID check but let's be more 402581ad6265SDimitry Andric // explicit about the error. 402681ad6265SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 402781ad6265SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 402881ad6265SDimitry Andric inconvertibleErrorCode(), "No current process and no PID provided")); 402981ad6265SDimitry Andric 403081ad6265SDimitry Andric // Check the process ID and find respective process instance. 403181ad6265SDimitry Andric auto new_process_it = m_debugged_processes.find(pid); 403281ad6265SDimitry Andric if (new_process_it == m_debugged_processes.end()) 403381ad6265SDimitry Andric return SendErrorResponse(1); 403481ad6265SDimitry Andric 403581ad6265SDimitry Andric // Check the thread ID 4036fcaf7f86SDimitry Andric if (!new_process_it->second.process_up->GetThreadByID(tid)) 403781ad6265SDimitry Andric return SendErrorResponse(2); 403881ad6265SDimitry Andric 403981ad6265SDimitry Andric return SendOKResponse(); 404081ad6265SDimitry Andric } 404181ad6265SDimitry Andric 40420b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { 404381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 40440b57cec5SDimitry Andric 40450b57cec5SDimitry Andric // Tell the stdio connection to shut down. 40460b57cec5SDimitry Andric if (m_stdio_communication.IsConnected()) { 40470b57cec5SDimitry Andric auto connection = m_stdio_communication.GetConnection(); 40480b57cec5SDimitry Andric if (connection) { 40490b57cec5SDimitry Andric Status error; 40500b57cec5SDimitry Andric connection->Disconnect(&error); 40510b57cec5SDimitry Andric 40520b57cec5SDimitry Andric if (error.Success()) { 40539dba64beSDimitry Andric LLDB_LOGF(log, 40549dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s disconnect process " 40550b57cec5SDimitry Andric "terminal stdio - SUCCESS", 40560b57cec5SDimitry Andric __FUNCTION__); 40570b57cec5SDimitry Andric } else { 40589dba64beSDimitry Andric LLDB_LOGF(log, 40599dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s disconnect process " 40600b57cec5SDimitry Andric "terminal stdio - FAIL: %s", 40610b57cec5SDimitry Andric __FUNCTION__, error.AsCString()); 40620b57cec5SDimitry Andric } 40630b57cec5SDimitry Andric } 40640b57cec5SDimitry Andric } 40650b57cec5SDimitry Andric } 40660b57cec5SDimitry Andric 40670b57cec5SDimitry Andric NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( 40680b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 40690b57cec5SDimitry Andric // We have no thread if we don't have a process. 4070fe6060f1SDimitry Andric if (!m_current_process || 4071fe6060f1SDimitry Andric m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) 40720b57cec5SDimitry Andric return nullptr; 40730b57cec5SDimitry Andric 40740b57cec5SDimitry Andric // If the client hasn't asked for thread suffix support, there will not be a 40750b57cec5SDimitry Andric // thread suffix. Use the current thread in that case. 40760b57cec5SDimitry Andric if (!m_thread_suffix_supported) { 40770b57cec5SDimitry Andric const lldb::tid_t current_tid = GetCurrentThreadID(); 40780b57cec5SDimitry Andric if (current_tid == LLDB_INVALID_THREAD_ID) 40790b57cec5SDimitry Andric return nullptr; 40800b57cec5SDimitry Andric else if (current_tid == 0) { 40810b57cec5SDimitry Andric // Pick a thread. 4082fe6060f1SDimitry Andric return m_current_process->GetThreadAtIndex(0); 40830b57cec5SDimitry Andric } else 4084fe6060f1SDimitry Andric return m_current_process->GetThreadByID(current_tid); 40850b57cec5SDimitry Andric } 40860b57cec5SDimitry Andric 408781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 40880b57cec5SDimitry Andric 40890b57cec5SDimitry Andric // Parse out the ';'. 40900b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') { 40919dba64beSDimitry Andric LLDB_LOGF(log, 40929dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " 40930b57cec5SDimitry Andric "error: expected ';' prior to start of thread suffix: packet " 40940b57cec5SDimitry Andric "contents = '%s'", 40959dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 40960b57cec5SDimitry Andric return nullptr; 40970b57cec5SDimitry Andric } 40980b57cec5SDimitry Andric 40990b57cec5SDimitry Andric if (!packet.GetBytesLeft()) 41000b57cec5SDimitry Andric return nullptr; 41010b57cec5SDimitry Andric 41020b57cec5SDimitry Andric // Parse out thread: portion. 41030b57cec5SDimitry Andric if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) { 41049dba64beSDimitry Andric LLDB_LOGF(log, 41059dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " 41060b57cec5SDimitry Andric "error: expected 'thread:' but not found, packet contents = " 41070b57cec5SDimitry Andric "'%s'", 41089dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 41090b57cec5SDimitry Andric return nullptr; 41100b57cec5SDimitry Andric } 41110b57cec5SDimitry Andric packet.SetFilePos(packet.GetFilePos() + strlen("thread:")); 41120b57cec5SDimitry Andric const lldb::tid_t tid = packet.GetHexMaxU64(false, 0); 41130b57cec5SDimitry Andric if (tid != 0) 4114fe6060f1SDimitry Andric return m_current_process->GetThreadByID(tid); 41150b57cec5SDimitry Andric 41160b57cec5SDimitry Andric return nullptr; 41170b57cec5SDimitry Andric } 41180b57cec5SDimitry Andric 41190b57cec5SDimitry Andric lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const { 41200b57cec5SDimitry Andric if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) { 41210b57cec5SDimitry Andric // Use whatever the debug process says is the current thread id since the 41220b57cec5SDimitry Andric // protocol either didn't specify or specified we want any/all threads 41230b57cec5SDimitry Andric // marked as the current thread. 4124fe6060f1SDimitry Andric if (!m_current_process) 41250b57cec5SDimitry Andric return LLDB_INVALID_THREAD_ID; 4126fe6060f1SDimitry Andric return m_current_process->GetCurrentThreadID(); 41270b57cec5SDimitry Andric } 41280b57cec5SDimitry Andric // Use the specific current thread id set by the gdb remote protocol. 41290b57cec5SDimitry Andric return m_current_tid; 41300b57cec5SDimitry Andric } 41310b57cec5SDimitry Andric 41320b57cec5SDimitry Andric uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() { 41330b57cec5SDimitry Andric std::lock_guard<std::mutex> guard(m_saved_registers_mutex); 41340b57cec5SDimitry Andric return m_next_saved_registers_id++; 41350b57cec5SDimitry Andric } 41360b57cec5SDimitry Andric 41370b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() { 413881ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 41390b57cec5SDimitry Andric 41400b57cec5SDimitry Andric LLDB_LOG(log, "clearing {0} xfer buffers", m_xfer_buffer_map.size()); 41410b57cec5SDimitry Andric m_xfer_buffer_map.clear(); 41420b57cec5SDimitry Andric } 41430b57cec5SDimitry Andric 41440b57cec5SDimitry Andric FileSpec 41450b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path, 41460b57cec5SDimitry Andric const ArchSpec &arch) { 4147fe6060f1SDimitry Andric if (m_current_process) { 41480b57cec5SDimitry Andric FileSpec file_spec; 4149fe6060f1SDimitry Andric if (m_current_process 41500b57cec5SDimitry Andric ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec) 41510b57cec5SDimitry Andric .Success()) { 41520b57cec5SDimitry Andric if (FileSystem::Instance().Exists(file_spec)) 41530b57cec5SDimitry Andric return file_spec; 41540b57cec5SDimitry Andric } 41550b57cec5SDimitry Andric } 41560b57cec5SDimitry Andric 41570b57cec5SDimitry Andric return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch); 41580b57cec5SDimitry Andric } 41599dba64beSDimitry Andric 41609dba64beSDimitry Andric std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue( 41619dba64beSDimitry Andric llvm::StringRef value) { 41629dba64beSDimitry Andric std::string result; 41639dba64beSDimitry Andric for (const char &c : value) { 41649dba64beSDimitry Andric switch (c) { 41659dba64beSDimitry Andric case '\'': 41669dba64beSDimitry Andric result += "'"; 41679dba64beSDimitry Andric break; 41689dba64beSDimitry Andric case '"': 41699dba64beSDimitry Andric result += """; 41709dba64beSDimitry Andric break; 41719dba64beSDimitry Andric case '<': 41729dba64beSDimitry Andric result += "<"; 41739dba64beSDimitry Andric break; 41749dba64beSDimitry Andric case '>': 41759dba64beSDimitry Andric result += ">"; 41769dba64beSDimitry Andric break; 41779dba64beSDimitry Andric default: 41789dba64beSDimitry Andric result += c; 41799dba64beSDimitry Andric break; 41809dba64beSDimitry Andric } 41819dba64beSDimitry Andric } 41829dba64beSDimitry Andric return result; 41839dba64beSDimitry Andric } 4184fe6060f1SDimitry Andric 4185fe6060f1SDimitry Andric std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures( 4186fe6060f1SDimitry Andric const llvm::ArrayRef<llvm::StringRef> client_features) { 4187fe6060f1SDimitry Andric std::vector<std::string> ret = 4188fe6060f1SDimitry Andric GDBRemoteCommunicationServerCommon::HandleFeatures(client_features); 4189fe6060f1SDimitry Andric ret.insert(ret.end(), { 4190fe6060f1SDimitry Andric "QThreadSuffixSupported+", 4191fe6060f1SDimitry Andric "QListThreadsInStopReply+", 4192fe6060f1SDimitry Andric "qXfer:features:read+", 419381ad6265SDimitry Andric "QNonStop+", 4194fe6060f1SDimitry Andric }); 4195fe6060f1SDimitry Andric 4196fe6060f1SDimitry Andric // report server-only features 4197fe6060f1SDimitry Andric using Extension = NativeProcessProtocol::Extension; 4198fe6060f1SDimitry Andric Extension plugin_features = m_process_factory.GetSupportedExtensions(); 4199fe6060f1SDimitry Andric if (bool(plugin_features & Extension::pass_signals)) 4200fe6060f1SDimitry Andric ret.push_back("QPassSignals+"); 4201fe6060f1SDimitry Andric if (bool(plugin_features & Extension::auxv)) 4202fe6060f1SDimitry Andric ret.push_back("qXfer:auxv:read+"); 4203fe6060f1SDimitry Andric if (bool(plugin_features & Extension::libraries_svr4)) 4204fe6060f1SDimitry Andric ret.push_back("qXfer:libraries-svr4:read+"); 420504eeddc0SDimitry Andric if (bool(plugin_features & Extension::siginfo_read)) 420604eeddc0SDimitry Andric ret.push_back("qXfer:siginfo:read+"); 4207fe6060f1SDimitry Andric if (bool(plugin_features & Extension::memory_tagging)) 4208fe6060f1SDimitry Andric ret.push_back("memory-tagging+"); 4209349cc55cSDimitry Andric if (bool(plugin_features & Extension::savecore)) 4210349cc55cSDimitry Andric ret.push_back("qSaveCore+"); 4211fe6060f1SDimitry Andric 4212fe6060f1SDimitry Andric // check for client features 4213fe6060f1SDimitry Andric m_extensions_supported = {}; 4214fe6060f1SDimitry Andric for (llvm::StringRef x : client_features) 4215fe6060f1SDimitry Andric m_extensions_supported |= 4216fe6060f1SDimitry Andric llvm::StringSwitch<Extension>(x) 4217fe6060f1SDimitry Andric .Case("multiprocess+", Extension::multiprocess) 4218fe6060f1SDimitry Andric .Case("fork-events+", Extension::fork) 4219fe6060f1SDimitry Andric .Case("vfork-events+", Extension::vfork) 4220fe6060f1SDimitry Andric .Default({}); 4221fe6060f1SDimitry Andric 4222fe6060f1SDimitry Andric m_extensions_supported &= plugin_features; 4223fe6060f1SDimitry Andric 4224fe6060f1SDimitry Andric // fork & vfork require multiprocess 4225fe6060f1SDimitry Andric if (!bool(m_extensions_supported & Extension::multiprocess)) 4226fe6060f1SDimitry Andric m_extensions_supported &= ~(Extension::fork | Extension::vfork); 4227fe6060f1SDimitry Andric 4228fe6060f1SDimitry Andric // report only if actually supported 4229fe6060f1SDimitry Andric if (bool(m_extensions_supported & Extension::multiprocess)) 4230fe6060f1SDimitry Andric ret.push_back("multiprocess+"); 4231fe6060f1SDimitry Andric if (bool(m_extensions_supported & Extension::fork)) 4232fe6060f1SDimitry Andric ret.push_back("fork-events+"); 4233fe6060f1SDimitry Andric if (bool(m_extensions_supported & Extension::vfork)) 4234fe6060f1SDimitry Andric ret.push_back("vfork-events+"); 4235fe6060f1SDimitry Andric 4236fe6060f1SDimitry Andric for (auto &x : m_debugged_processes) 4237fcaf7f86SDimitry Andric SetEnabledExtensions(*x.second.process_up); 4238fe6060f1SDimitry Andric return ret; 4239fe6060f1SDimitry Andric } 4240fe6060f1SDimitry Andric 4241fe6060f1SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions( 4242fe6060f1SDimitry Andric NativeProcessProtocol &process) { 4243fe6060f1SDimitry Andric NativeProcessProtocol::Extension flags = m_extensions_supported; 4244fe6060f1SDimitry Andric assert(!bool(flags & ~m_process_factory.GetSupportedExtensions())); 4245fe6060f1SDimitry Andric process.SetEnabledExtensions(flags); 4246fe6060f1SDimitry Andric } 4247349cc55cSDimitry Andric 424881ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 424981ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::SendContinueSuccessResponse() { 4250fcaf7f86SDimitry Andric if (m_non_stop) 4251fcaf7f86SDimitry Andric return SendOKResponse(); 425281ad6265SDimitry Andric StartSTDIOForwarding(); 4253fcaf7f86SDimitry Andric return PacketResult::Success; 425481ad6265SDimitry Andric } 425581ad6265SDimitry Andric 425681ad6265SDimitry Andric void GDBRemoteCommunicationServerLLGS::AppendThreadIDToResponse( 425781ad6265SDimitry Andric Stream &response, lldb::pid_t pid, lldb::tid_t tid) { 425881ad6265SDimitry Andric if (bool(m_extensions_supported & 425981ad6265SDimitry Andric NativeProcessProtocol::Extension::multiprocess)) 426081ad6265SDimitry Andric response.Format("p{0:x-}.", pid); 426181ad6265SDimitry Andric response.Format("{0:x-}", tid); 426281ad6265SDimitry Andric } 426381ad6265SDimitry Andric 4264349cc55cSDimitry Andric std::string 4265349cc55cSDimitry Andric lldb_private::process_gdb_remote::LLGSArgToURL(llvm::StringRef url_arg, 4266349cc55cSDimitry Andric bool reverse_connect) { 4267349cc55cSDimitry Andric // Try parsing the argument as URL. 4268349cc55cSDimitry Andric if (llvm::Optional<URI> url = URI::Parse(url_arg)) { 4269349cc55cSDimitry Andric if (reverse_connect) 4270349cc55cSDimitry Andric return url_arg.str(); 4271349cc55cSDimitry Andric 4272349cc55cSDimitry Andric // Translate the scheme from LLGS notation to ConnectionFileDescriptor. 4273349cc55cSDimitry Andric // If the scheme doesn't match any, pass it through to support using CFD 4274349cc55cSDimitry Andric // schemes directly. 4275349cc55cSDimitry Andric std::string new_url = llvm::StringSwitch<std::string>(url->scheme) 4276349cc55cSDimitry Andric .Case("tcp", "listen") 4277349cc55cSDimitry Andric .Case("unix", "unix-accept") 4278349cc55cSDimitry Andric .Case("unix-abstract", "unix-abstract-accept") 4279349cc55cSDimitry Andric .Default(url->scheme.str()); 4280349cc55cSDimitry Andric llvm::append_range(new_url, url_arg.substr(url->scheme.size())); 4281349cc55cSDimitry Andric return new_url; 4282349cc55cSDimitry Andric } 4283349cc55cSDimitry Andric 4284349cc55cSDimitry Andric std::string host_port = url_arg.str(); 4285349cc55cSDimitry Andric // If host_and_port starts with ':', default the host to be "localhost" and 4286349cc55cSDimitry Andric // expect the remainder to be the port. 4287349cc55cSDimitry Andric if (url_arg.startswith(":")) 4288349cc55cSDimitry Andric host_port.insert(0, "localhost"); 4289349cc55cSDimitry Andric 4290349cc55cSDimitry Andric // Try parsing the (preprocessed) argument as host:port pair. 4291349cc55cSDimitry Andric if (!llvm::errorToBool(Socket::DecodeHostAndPort(host_port).takeError())) 4292349cc55cSDimitry Andric return (reverse_connect ? "connect://" : "listen://") + host_port; 4293349cc55cSDimitry Andric 4294349cc55cSDimitry Andric // If none of the above applied, interpret the argument as UNIX socket path. 4295349cc55cSDimitry Andric return (reverse_connect ? "unix-connect://" : "unix-accept://") + 4296349cc55cSDimitry Andric url_arg.str(); 4297349cc55cSDimitry Andric } 4298