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( 24981ad6265SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vStopped, 25081ad6265SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vStopped); 25181ad6265SDimitry Andric RegisterMemberFunctionHandler( 25281ad6265SDimitry Andric StringExtractorGDBRemote::eServerPacketType_vCtrlC, 25381ad6265SDimitry Andric &GDBRemoteCommunicationServerLLGS::Handle_vCtrlC); 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) { 2570b57cec5SDimitry Andric m_process_launch_info = info; 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { 26181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric if (!m_process_launch_info.GetArguments().GetArgumentCount()) 2640b57cec5SDimitry Andric return Status("%s: no process command line specified to launch", 2650b57cec5SDimitry Andric __FUNCTION__); 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric const bool should_forward_stdio = 2680b57cec5SDimitry Andric m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr || 2690b57cec5SDimitry Andric m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr || 2700b57cec5SDimitry Andric m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr; 2710b57cec5SDimitry Andric m_process_launch_info.SetLaunchInSeparateProcessGroup(true); 2720b57cec5SDimitry Andric m_process_launch_info.GetFlags().Set(eLaunchFlagDebug); 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric if (should_forward_stdio) { 2759dba64beSDimitry Andric // Temporarily relax the following for Windows until we can take advantage 2769dba64beSDimitry Andric // of the recently added pty support. This doesn't really affect the use of 2779dba64beSDimitry Andric // lldb-server on Windows. 2789dba64beSDimitry Andric #if !defined(_WIN32) 2790b57cec5SDimitry Andric if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection()) 2800b57cec5SDimitry Andric return Status(std::move(Err)); 2819dba64beSDimitry Andric #endif 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric { 2850b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex); 286fe6060f1SDimitry Andric assert(m_debugged_processes.empty() && "lldb-server creating debugged " 2870b57cec5SDimitry Andric "process but one already exists"); 2880b57cec5SDimitry Andric auto process_or = 2890b57cec5SDimitry Andric m_process_factory.Launch(m_process_launch_info, *this, m_mainloop); 2900b57cec5SDimitry Andric if (!process_or) 2910b57cec5SDimitry Andric return Status(process_or.takeError()); 292fe6060f1SDimitry Andric m_continue_process = m_current_process = process_or->get(); 293fe6060f1SDimitry Andric m_debugged_processes[m_current_process->GetID()] = std::move(*process_or); 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric 296fe6060f1SDimitry Andric SetEnabledExtensions(*m_current_process); 297fe6060f1SDimitry Andric 2980b57cec5SDimitry Andric // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as 2990b57cec5SDimitry Andric // needed. llgs local-process debugging may specify PTY paths, which will 3000b57cec5SDimitry Andric // make these file actions non-null process launch -i/e/o will also make 3010b57cec5SDimitry Andric // these file actions non-null nullptr means that the traffic is expected to 3020b57cec5SDimitry Andric // flow over gdb-remote protocol 3030b57cec5SDimitry Andric if (should_forward_stdio) { 3040b57cec5SDimitry Andric // nullptr means it's not redirected to file or pty (in case of LLGS local) 3050b57cec5SDimitry Andric // at least one of stdio will be transferred pty<->gdb-remote we need to 306349cc55cSDimitry Andric // give the pty primary handle to this object to read and/or write 3070b57cec5SDimitry Andric LLDB_LOG(log, 3080b57cec5SDimitry Andric "pid = {0}: setting up stdout/stderr redirection via $O " 3090b57cec5SDimitry Andric "gdb-remote commands", 310fe6060f1SDimitry Andric m_current_process->GetID()); 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric // Setup stdout/stderr mapping from inferior to $O 313fe6060f1SDimitry Andric auto terminal_fd = m_current_process->GetTerminalFileDescriptor(); 3140b57cec5SDimitry Andric if (terminal_fd >= 0) { 3159dba64beSDimitry Andric LLDB_LOGF(log, 3169dba64beSDimitry Andric "ProcessGDBRemoteCommunicationServerLLGS::%s setting " 3170b57cec5SDimitry Andric "inferior STDIO fd to %d", 3180b57cec5SDimitry Andric __FUNCTION__, terminal_fd); 3190b57cec5SDimitry Andric Status status = SetSTDIOFileDescriptor(terminal_fd); 3200b57cec5SDimitry Andric if (status.Fail()) 3210b57cec5SDimitry Andric return status; 3220b57cec5SDimitry Andric } else { 3239dba64beSDimitry Andric LLDB_LOGF(log, 3249dba64beSDimitry Andric "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " 3250b57cec5SDimitry Andric "inferior STDIO since terminal fd reported as %d", 3260b57cec5SDimitry Andric __FUNCTION__, terminal_fd); 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric } else { 3290b57cec5SDimitry Andric LLDB_LOG(log, 3300b57cec5SDimitry Andric "pid = {0} skipping stdout/stderr redirection via $O: inferior " 3310b57cec5SDimitry Andric "will communicate over client-provided file descriptors", 332fe6060f1SDimitry Andric m_current_process->GetID()); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric printf("Launched '%s' as process %" PRIu64 "...\n", 3360b57cec5SDimitry Andric m_process_launch_info.GetArguments().GetArgumentAtIndex(0), 337fe6060f1SDimitry Andric m_current_process->GetID()); 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric return Status(); 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { 34381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3449dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, 3450b57cec5SDimitry Andric __FUNCTION__, pid); 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric // Before we try to attach, make sure we aren't already monitoring something 3480b57cec5SDimitry Andric // else. 349fe6060f1SDimitry Andric if (!m_debugged_processes.empty()) 3500b57cec5SDimitry Andric return Status("cannot attach to process %" PRIu64 3510b57cec5SDimitry Andric " when another process with pid %" PRIu64 3520b57cec5SDimitry Andric " is being debugged.", 353fe6060f1SDimitry Andric pid, m_current_process->GetID()); 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric // Try to attach. 3560b57cec5SDimitry Andric auto process_or = m_process_factory.Attach(pid, *this, m_mainloop); 3570b57cec5SDimitry Andric if (!process_or) { 3580b57cec5SDimitry Andric Status status(process_or.takeError()); 359349cc55cSDimitry Andric llvm::errs() << llvm::formatv("failed to attach to process {0}: {1}\n", pid, 3600b57cec5SDimitry Andric status); 3610b57cec5SDimitry Andric return status; 3620b57cec5SDimitry Andric } 363fe6060f1SDimitry Andric m_continue_process = m_current_process = process_or->get(); 364fe6060f1SDimitry Andric m_debugged_processes[m_current_process->GetID()] = std::move(*process_or); 365fe6060f1SDimitry Andric SetEnabledExtensions(*m_current_process); 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric // Setup stdout/stderr mapping from inferior. 368fe6060f1SDimitry Andric auto terminal_fd = m_current_process->GetTerminalFileDescriptor(); 3690b57cec5SDimitry Andric if (terminal_fd >= 0) { 3709dba64beSDimitry Andric LLDB_LOGF(log, 3719dba64beSDimitry Andric "ProcessGDBRemoteCommunicationServerLLGS::%s setting " 3720b57cec5SDimitry Andric "inferior STDIO fd to %d", 3730b57cec5SDimitry Andric __FUNCTION__, terminal_fd); 3740b57cec5SDimitry Andric Status status = SetSTDIOFileDescriptor(terminal_fd); 3750b57cec5SDimitry Andric if (status.Fail()) 3760b57cec5SDimitry Andric return status; 3770b57cec5SDimitry Andric } else { 3789dba64beSDimitry Andric LLDB_LOGF(log, 3799dba64beSDimitry Andric "ProcessGDBRemoteCommunicationServerLLGS::%s ignoring " 3800b57cec5SDimitry Andric "inferior STDIO since terminal fd reported as %d", 3810b57cec5SDimitry Andric __FUNCTION__, terminal_fd); 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric printf("Attached to process %" PRIu64 "...\n", pid); 3850b57cec5SDimitry Andric return Status(); 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 388e8d8bef9SDimitry Andric Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess( 389e8d8bef9SDimitry Andric llvm::StringRef process_name, bool include_existing) { 39081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 391e8d8bef9SDimitry Andric 392e8d8bef9SDimitry Andric std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1); 393e8d8bef9SDimitry Andric 394e8d8bef9SDimitry Andric // Create the matcher used to search the process list. 395e8d8bef9SDimitry Andric ProcessInstanceInfoList exclusion_list; 396e8d8bef9SDimitry Andric ProcessInstanceInfoMatch match_info; 397e8d8bef9SDimitry Andric match_info.GetProcessInfo().GetExecutableFile().SetFile( 398e8d8bef9SDimitry Andric process_name, llvm::sys::path::Style::native); 399e8d8bef9SDimitry Andric match_info.SetNameMatchType(NameMatch::Equals); 400e8d8bef9SDimitry Andric 401e8d8bef9SDimitry Andric if (include_existing) { 402e8d8bef9SDimitry Andric LLDB_LOG(log, "including existing processes in search"); 403e8d8bef9SDimitry Andric } else { 404e8d8bef9SDimitry Andric // Create the excluded process list before polling begins. 405e8d8bef9SDimitry Andric Host::FindProcesses(match_info, exclusion_list); 406e8d8bef9SDimitry Andric LLDB_LOG(log, "placed '{0}' processes in the exclusion list.", 407e8d8bef9SDimitry Andric exclusion_list.size()); 408e8d8bef9SDimitry Andric } 409e8d8bef9SDimitry Andric 410e8d8bef9SDimitry Andric LLDB_LOG(log, "waiting for '{0}' to appear", process_name); 411e8d8bef9SDimitry Andric 412e8d8bef9SDimitry Andric auto is_in_exclusion_list = 413e8d8bef9SDimitry Andric [&exclusion_list](const ProcessInstanceInfo &info) { 414e8d8bef9SDimitry Andric for (auto &excluded : exclusion_list) { 415e8d8bef9SDimitry Andric if (excluded.GetProcessID() == info.GetProcessID()) 416e8d8bef9SDimitry Andric return true; 417e8d8bef9SDimitry Andric } 418e8d8bef9SDimitry Andric return false; 419e8d8bef9SDimitry Andric }; 420e8d8bef9SDimitry Andric 421e8d8bef9SDimitry Andric ProcessInstanceInfoList loop_process_list; 422e8d8bef9SDimitry Andric while (true) { 423e8d8bef9SDimitry Andric loop_process_list.clear(); 424e8d8bef9SDimitry Andric if (Host::FindProcesses(match_info, loop_process_list)) { 425e8d8bef9SDimitry Andric // Remove all the elements that are in the exclusion list. 426e8d8bef9SDimitry Andric llvm::erase_if(loop_process_list, is_in_exclusion_list); 427e8d8bef9SDimitry Andric 428e8d8bef9SDimitry Andric // One match! We found the desired process. 429e8d8bef9SDimitry Andric if (loop_process_list.size() == 1) { 430e8d8bef9SDimitry Andric auto matching_process_pid = loop_process_list[0].GetProcessID(); 431e8d8bef9SDimitry Andric LLDB_LOG(log, "found pid {0}", matching_process_pid); 432e8d8bef9SDimitry Andric return AttachToProcess(matching_process_pid); 433e8d8bef9SDimitry Andric } 434e8d8bef9SDimitry Andric 435e8d8bef9SDimitry Andric // Multiple matches! Return an error reporting the PIDs we found. 436e8d8bef9SDimitry Andric if (loop_process_list.size() > 1) { 437e8d8bef9SDimitry Andric StreamString error_stream; 438e8d8bef9SDimitry Andric error_stream.Format( 439e8d8bef9SDimitry Andric "Multiple executables with name: '{0}' found. Pids: ", 440e8d8bef9SDimitry Andric process_name); 441e8d8bef9SDimitry Andric for (size_t i = 0; i < loop_process_list.size() - 1; ++i) { 442e8d8bef9SDimitry Andric error_stream.Format("{0}, ", loop_process_list[i].GetProcessID()); 443e8d8bef9SDimitry Andric } 444e8d8bef9SDimitry Andric error_stream.Format("{0}.", loop_process_list.back().GetProcessID()); 445e8d8bef9SDimitry Andric 446e8d8bef9SDimitry Andric Status error; 447e8d8bef9SDimitry Andric error.SetErrorString(error_stream.GetString()); 448e8d8bef9SDimitry Andric return error; 449e8d8bef9SDimitry Andric } 450e8d8bef9SDimitry Andric } 451e8d8bef9SDimitry Andric // No matches, we have not found the process. Sleep until next poll. 452e8d8bef9SDimitry Andric LLDB_LOG(log, "sleep {0} seconds", polling_interval); 453e8d8bef9SDimitry Andric std::this_thread::sleep_for(polling_interval); 454e8d8bef9SDimitry Andric } 455e8d8bef9SDimitry Andric } 456e8d8bef9SDimitry Andric 4570b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::InitializeDelegate( 4580b57cec5SDimitry Andric NativeProcessProtocol *process) { 4590b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 46081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 4610b57cec5SDimitry Andric if (log) { 4629dba64beSDimitry Andric LLDB_LOGF(log, 4639dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s called with " 4640b57cec5SDimitry Andric "NativeProcessProtocol pid %" PRIu64 ", current state: %s", 4650b57cec5SDimitry Andric __FUNCTION__, process->GetID(), 4660b57cec5SDimitry Andric StateAsCString(process->GetState())); 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 4710b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendWResponse( 4720b57cec5SDimitry Andric NativeProcessProtocol *process) { 4730b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 47481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric // send W notification 4770b57cec5SDimitry Andric auto wait_status = process->GetExitStatus(); 4780b57cec5SDimitry Andric if (!wait_status) { 4790b57cec5SDimitry Andric LLDB_LOG(log, "pid = {0}, failed to retrieve process exit status", 4800b57cec5SDimitry Andric process->GetID()); 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric StreamGDBRemote response; 4830b57cec5SDimitry Andric response.PutChar('E'); 4840b57cec5SDimitry Andric response.PutHex8(GDBRemoteServerError::eErrorExitStatus); 4850b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric 4880b57cec5SDimitry Andric LLDB_LOG(log, "pid = {0}, returning exit type {1}", process->GetID(), 4890b57cec5SDimitry Andric *wait_status); 4900b57cec5SDimitry Andric 49181ad6265SDimitry Andric // If the process was killed through vKill, return "OK". 49281ad6265SDimitry Andric if (m_vkilled_processes.find(process->GetID()) != m_vkilled_processes.end()) 49381ad6265SDimitry Andric return SendOKResponse(); 49481ad6265SDimitry Andric 4950b57cec5SDimitry Andric StreamGDBRemote response; 4960b57cec5SDimitry Andric response.Format("{0:g}", *wait_status); 49781ad6265SDimitry Andric if (bool(m_extensions_supported & NativeProcessProtocol::Extension::multiprocess)) 49881ad6265SDimitry Andric response.Format(";process:{0:x-}", process->GetID()); 49981ad6265SDimitry Andric if (m_non_stop) 50081ad6265SDimitry Andric return SendNotificationPacketNoLock("Stop", m_stop_notification_queue, 50181ad6265SDimitry Andric response.GetString()); 5020b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric static void AppendHexValue(StreamString &response, const uint8_t *buf, 5060b57cec5SDimitry Andric uint32_t buf_size, bool swap) { 5070b57cec5SDimitry Andric int64_t i; 5080b57cec5SDimitry Andric if (swap) { 5090b57cec5SDimitry Andric for (i = buf_size - 1; i >= 0; i--) 5100b57cec5SDimitry Andric response.PutHex8(buf[i]); 5110b57cec5SDimitry Andric } else { 5120b57cec5SDimitry Andric for (i = 0; i < buf_size; i++) 5130b57cec5SDimitry Andric response.PutHex8(buf[i]); 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric 5175ffd83dbSDimitry Andric static llvm::StringRef GetEncodingNameOrEmpty(const RegisterInfo ®_info) { 5185ffd83dbSDimitry Andric switch (reg_info.encoding) { 5195ffd83dbSDimitry Andric case eEncodingUint: 5205ffd83dbSDimitry Andric return "uint"; 5215ffd83dbSDimitry Andric case eEncodingSint: 5225ffd83dbSDimitry Andric return "sint"; 5235ffd83dbSDimitry Andric case eEncodingIEEE754: 5245ffd83dbSDimitry Andric return "ieee754"; 5255ffd83dbSDimitry Andric case eEncodingVector: 5265ffd83dbSDimitry Andric return "vector"; 5275ffd83dbSDimitry Andric default: 5285ffd83dbSDimitry Andric return ""; 5295ffd83dbSDimitry Andric } 5305ffd83dbSDimitry Andric } 5315ffd83dbSDimitry Andric 5325ffd83dbSDimitry Andric static llvm::StringRef GetFormatNameOrEmpty(const RegisterInfo ®_info) { 5335ffd83dbSDimitry Andric switch (reg_info.format) { 5345ffd83dbSDimitry Andric case eFormatBinary: 5355ffd83dbSDimitry Andric return "binary"; 5365ffd83dbSDimitry Andric case eFormatDecimal: 5375ffd83dbSDimitry Andric return "decimal"; 5385ffd83dbSDimitry Andric case eFormatHex: 5395ffd83dbSDimitry Andric return "hex"; 5405ffd83dbSDimitry Andric case eFormatFloat: 5415ffd83dbSDimitry Andric return "float"; 5425ffd83dbSDimitry Andric case eFormatVectorOfSInt8: 5435ffd83dbSDimitry Andric return "vector-sint8"; 5445ffd83dbSDimitry Andric case eFormatVectorOfUInt8: 5455ffd83dbSDimitry Andric return "vector-uint8"; 5465ffd83dbSDimitry Andric case eFormatVectorOfSInt16: 5475ffd83dbSDimitry Andric return "vector-sint16"; 5485ffd83dbSDimitry Andric case eFormatVectorOfUInt16: 5495ffd83dbSDimitry Andric return "vector-uint16"; 5505ffd83dbSDimitry Andric case eFormatVectorOfSInt32: 5515ffd83dbSDimitry Andric return "vector-sint32"; 5525ffd83dbSDimitry Andric case eFormatVectorOfUInt32: 5535ffd83dbSDimitry Andric return "vector-uint32"; 5545ffd83dbSDimitry Andric case eFormatVectorOfFloat32: 5555ffd83dbSDimitry Andric return "vector-float32"; 5565ffd83dbSDimitry Andric case eFormatVectorOfUInt64: 5575ffd83dbSDimitry Andric return "vector-uint64"; 5585ffd83dbSDimitry Andric case eFormatVectorOfUInt128: 5595ffd83dbSDimitry Andric return "vector-uint128"; 5605ffd83dbSDimitry Andric default: 5615ffd83dbSDimitry Andric return ""; 5625ffd83dbSDimitry Andric }; 5635ffd83dbSDimitry Andric } 5645ffd83dbSDimitry Andric 5655ffd83dbSDimitry Andric static llvm::StringRef GetKindGenericOrEmpty(const RegisterInfo ®_info) { 5665ffd83dbSDimitry Andric switch (reg_info.kinds[RegisterKind::eRegisterKindGeneric]) { 5675ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_PC: 5685ffd83dbSDimitry Andric return "pc"; 5695ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_SP: 5705ffd83dbSDimitry Andric return "sp"; 5715ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_FP: 5725ffd83dbSDimitry Andric return "fp"; 5735ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_RA: 5745ffd83dbSDimitry Andric return "ra"; 5755ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_FLAGS: 5765ffd83dbSDimitry Andric return "flags"; 5775ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG1: 5785ffd83dbSDimitry Andric return "arg1"; 5795ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG2: 5805ffd83dbSDimitry Andric return "arg2"; 5815ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG3: 5825ffd83dbSDimitry Andric return "arg3"; 5835ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG4: 5845ffd83dbSDimitry Andric return "arg4"; 5855ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG5: 5865ffd83dbSDimitry Andric return "arg5"; 5875ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG6: 5885ffd83dbSDimitry Andric return "arg6"; 5895ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG7: 5905ffd83dbSDimitry Andric return "arg7"; 5915ffd83dbSDimitry Andric case LLDB_REGNUM_GENERIC_ARG8: 5925ffd83dbSDimitry Andric return "arg8"; 5935ffd83dbSDimitry Andric default: 5945ffd83dbSDimitry Andric return ""; 5955ffd83dbSDimitry Andric } 5965ffd83dbSDimitry Andric } 5975ffd83dbSDimitry Andric 5985ffd83dbSDimitry Andric static void CollectRegNums(const uint32_t *reg_num, StreamString &response, 5995ffd83dbSDimitry Andric bool usehex) { 6005ffd83dbSDimitry Andric for (int i = 0; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) { 6015ffd83dbSDimitry Andric if (i > 0) 6025ffd83dbSDimitry Andric response.PutChar(','); 6035ffd83dbSDimitry Andric if (usehex) 6045ffd83dbSDimitry Andric response.Printf("%" PRIx32, *reg_num); 6055ffd83dbSDimitry Andric else 6065ffd83dbSDimitry Andric response.Printf("%" PRIu32, *reg_num); 6075ffd83dbSDimitry Andric } 6085ffd83dbSDimitry Andric } 6095ffd83dbSDimitry Andric 6100b57cec5SDimitry Andric static void WriteRegisterValueInHexFixedWidth( 6110b57cec5SDimitry Andric StreamString &response, NativeRegisterContext ®_ctx, 6120b57cec5SDimitry Andric const RegisterInfo ®_info, const RegisterValue *reg_value_p, 6130b57cec5SDimitry Andric lldb::ByteOrder byte_order) { 6140b57cec5SDimitry Andric RegisterValue reg_value; 6150b57cec5SDimitry Andric if (!reg_value_p) { 6160b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(®_info, reg_value); 6170b57cec5SDimitry Andric if (error.Success()) 6180b57cec5SDimitry Andric reg_value_p = ®_value; 6190b57cec5SDimitry Andric // else log. 6200b57cec5SDimitry Andric } 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric if (reg_value_p) { 6230b57cec5SDimitry Andric AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(), 6240b57cec5SDimitry Andric reg_value_p->GetByteSize(), 6250b57cec5SDimitry Andric byte_order == lldb::eByteOrderLittle); 6260b57cec5SDimitry Andric } else { 6270b57cec5SDimitry Andric // Zero-out any unreadable values. 6280b57cec5SDimitry Andric if (reg_info.byte_size > 0) { 6290b57cec5SDimitry Andric std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0'); 6300b57cec5SDimitry Andric AppendHexValue(response, zeros.data(), zeros.size(), false); 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric } 6340b57cec5SDimitry Andric 635e8d8bef9SDimitry Andric static llvm::Optional<json::Object> 6369dba64beSDimitry Andric GetRegistersAsJSON(NativeThreadProtocol &thread) { 63781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric NativeRegisterContext& reg_ctx = thread.GetRegisterContext(); 6400b57cec5SDimitry Andric 6419dba64beSDimitry Andric json::Object register_object; 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric #ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET 644e8d8bef9SDimitry Andric const auto expedited_regs = 645e8d8bef9SDimitry Andric reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full); 6460b57cec5SDimitry Andric #else 647e8d8bef9SDimitry Andric const auto expedited_regs = 648e8d8bef9SDimitry Andric reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Minimal); 6490b57cec5SDimitry Andric #endif 650e8d8bef9SDimitry Andric if (expedited_regs.empty()) 651e8d8bef9SDimitry Andric return llvm::None; 6520b57cec5SDimitry Andric 653e8d8bef9SDimitry Andric for (auto ®_num : expedited_regs) { 6540b57cec5SDimitry Andric const RegisterInfo *const reg_info_p = 6550b57cec5SDimitry Andric reg_ctx.GetRegisterInfoAtIndex(reg_num); 6560b57cec5SDimitry Andric if (reg_info_p == nullptr) { 6579dba64beSDimitry Andric LLDB_LOGF(log, 6580b57cec5SDimitry Andric "%s failed to get register info for register index %" PRIu32, 6590b57cec5SDimitry Andric __FUNCTION__, reg_num); 6600b57cec5SDimitry Andric continue; 6610b57cec5SDimitry Andric } 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric if (reg_info_p->value_regs != nullptr) 6640b57cec5SDimitry Andric continue; // Only expedite registers that are not contained in other 6650b57cec5SDimitry Andric // registers. 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric RegisterValue reg_value; 6680b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); 6690b57cec5SDimitry Andric if (error.Fail()) { 6709dba64beSDimitry Andric LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s", 6710b57cec5SDimitry Andric __FUNCTION__, 6720b57cec5SDimitry Andric reg_info_p->name ? reg_info_p->name : "<unnamed-register>", 6730b57cec5SDimitry Andric reg_num, error.AsCString()); 6740b57cec5SDimitry Andric continue; 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric StreamString stream; 6780b57cec5SDimitry Andric WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p, 6790b57cec5SDimitry Andric ®_value, lldb::eByteOrderBig); 6800b57cec5SDimitry Andric 6819dba64beSDimitry Andric register_object.try_emplace(llvm::to_string(reg_num), 6829dba64beSDimitry Andric stream.GetString().str()); 6830b57cec5SDimitry Andric } 6840b57cec5SDimitry Andric 6859dba64beSDimitry Andric return register_object; 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andric static const char *GetStopReasonString(StopReason stop_reason) { 6890b57cec5SDimitry Andric switch (stop_reason) { 6900b57cec5SDimitry Andric case eStopReasonTrace: 6910b57cec5SDimitry Andric return "trace"; 6920b57cec5SDimitry Andric case eStopReasonBreakpoint: 6930b57cec5SDimitry Andric return "breakpoint"; 6940b57cec5SDimitry Andric case eStopReasonWatchpoint: 6950b57cec5SDimitry Andric return "watchpoint"; 6960b57cec5SDimitry Andric case eStopReasonSignal: 6970b57cec5SDimitry Andric return "signal"; 6980b57cec5SDimitry Andric case eStopReasonException: 6990b57cec5SDimitry Andric return "exception"; 7000b57cec5SDimitry Andric case eStopReasonExec: 7010b57cec5SDimitry Andric return "exec"; 702fe6060f1SDimitry Andric case eStopReasonProcessorTrace: 703fe6060f1SDimitry Andric return "processor trace"; 704fe6060f1SDimitry Andric case eStopReasonFork: 705fe6060f1SDimitry Andric return "fork"; 706fe6060f1SDimitry Andric case eStopReasonVFork: 707fe6060f1SDimitry Andric return "vfork"; 708fe6060f1SDimitry Andric case eStopReasonVForkDone: 709fe6060f1SDimitry Andric return "vforkdone"; 7100b57cec5SDimitry Andric case eStopReasonInstrumentation: 7110b57cec5SDimitry Andric case eStopReasonInvalid: 7120b57cec5SDimitry Andric case eStopReasonPlanComplete: 7130b57cec5SDimitry Andric case eStopReasonThreadExiting: 7140b57cec5SDimitry Andric case eStopReasonNone: 7150b57cec5SDimitry Andric break; // ignored 7160b57cec5SDimitry Andric } 7170b57cec5SDimitry Andric return nullptr; 7180b57cec5SDimitry Andric } 7190b57cec5SDimitry Andric 7209dba64beSDimitry Andric static llvm::Expected<json::Array> 7219dba64beSDimitry Andric GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) { 72281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 7230b57cec5SDimitry Andric 7249dba64beSDimitry Andric json::Array threads_array; 7250b57cec5SDimitry Andric 7260b57cec5SDimitry Andric // Ensure we can get info on the given thread. 72781ad6265SDimitry Andric for (NativeThreadProtocol &thread : process.Threads()) { 72881ad6265SDimitry Andric lldb::tid_t tid = thread.GetID(); 7290b57cec5SDimitry Andric // Grab the reason this thread stopped. 7300b57cec5SDimitry Andric struct ThreadStopInfo tid_stop_info; 7310b57cec5SDimitry Andric std::string description; 73281ad6265SDimitry Andric if (!thread.GetStopReason(tid_stop_info, description)) 7339dba64beSDimitry Andric return llvm::make_error<llvm::StringError>( 7349dba64beSDimitry Andric "failed to get stop reason", llvm::inconvertibleErrorCode()); 7350b57cec5SDimitry Andric 73681ad6265SDimitry Andric const int signum = tid_stop_info.signo; 7370b57cec5SDimitry Andric if (log) { 7389dba64beSDimitry Andric LLDB_LOGF(log, 7399dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 7400b57cec5SDimitry Andric " tid %" PRIu64 7410b57cec5SDimitry Andric " got signal signo = %d, reason = %d, exc_type = %" PRIu64, 7420b57cec5SDimitry Andric __FUNCTION__, process.GetID(), tid, signum, 7430b57cec5SDimitry Andric tid_stop_info.reason, tid_stop_info.details.exception.type); 7440b57cec5SDimitry Andric } 7450b57cec5SDimitry Andric 7469dba64beSDimitry Andric json::Object thread_obj; 7470b57cec5SDimitry Andric 7480b57cec5SDimitry Andric if (!abridged) { 74981ad6265SDimitry Andric if (llvm::Optional<json::Object> registers = GetRegistersAsJSON(thread)) 7509dba64beSDimitry Andric thread_obj.try_emplace("registers", std::move(*registers)); 7510b57cec5SDimitry Andric } 7520b57cec5SDimitry Andric 7539dba64beSDimitry Andric thread_obj.try_emplace("tid", static_cast<int64_t>(tid)); 7549dba64beSDimitry Andric 7550b57cec5SDimitry Andric if (signum != 0) 7569dba64beSDimitry Andric thread_obj.try_emplace("signal", signum); 7570b57cec5SDimitry Andric 75881ad6265SDimitry Andric const std::string thread_name = thread.GetName(); 7590b57cec5SDimitry Andric if (!thread_name.empty()) 7609dba64beSDimitry Andric thread_obj.try_emplace("name", thread_name); 7610b57cec5SDimitry Andric 7629dba64beSDimitry Andric const char *stop_reason = GetStopReasonString(tid_stop_info.reason); 7639dba64beSDimitry Andric if (stop_reason) 7649dba64beSDimitry Andric thread_obj.try_emplace("reason", stop_reason); 7650b57cec5SDimitry Andric 7660b57cec5SDimitry Andric if (!description.empty()) 7679dba64beSDimitry Andric thread_obj.try_emplace("description", description); 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric if ((tid_stop_info.reason == eStopReasonException) && 7700b57cec5SDimitry Andric tid_stop_info.details.exception.type) { 7719dba64beSDimitry Andric thread_obj.try_emplace( 7729dba64beSDimitry Andric "metype", static_cast<int64_t>(tid_stop_info.details.exception.type)); 7730b57cec5SDimitry Andric 7749dba64beSDimitry Andric json::Array medata_array; 7750b57cec5SDimitry Andric for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; 7760b57cec5SDimitry Andric ++i) { 7779dba64beSDimitry Andric medata_array.push_back( 7789dba64beSDimitry Andric static_cast<int64_t>(tid_stop_info.details.exception.data[i])); 7790b57cec5SDimitry Andric } 7809dba64beSDimitry Andric thread_obj.try_emplace("medata", std::move(medata_array)); 7810b57cec5SDimitry Andric } 7829dba64beSDimitry Andric threads_array.push_back(std::move(thread_obj)); 7830b57cec5SDimitry Andric } 7849dba64beSDimitry Andric return threads_array; 7850b57cec5SDimitry Andric } 7860b57cec5SDimitry Andric 78781ad6265SDimitry Andric StreamString 78881ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::PrepareStopReplyPacketForThread( 78981ad6265SDimitry Andric NativeThreadProtocol &thread) { 79081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 7910b57cec5SDimitry Andric 79281ad6265SDimitry Andric NativeProcessProtocol &process = thread.GetProcess(); 7930b57cec5SDimitry Andric 79481ad6265SDimitry Andric LLDB_LOG(log, "preparing packet for pid {0} tid {1}", process.GetID(), 79581ad6265SDimitry Andric thread.GetID()); 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric // Grab the reason this thread stopped. 79881ad6265SDimitry Andric StreamString response; 7990b57cec5SDimitry Andric struct ThreadStopInfo tid_stop_info; 8000b57cec5SDimitry Andric std::string description; 80181ad6265SDimitry Andric if (!thread.GetStopReason(tid_stop_info, description)) 80281ad6265SDimitry Andric return response; 8030b57cec5SDimitry Andric 8040b57cec5SDimitry Andric // FIXME implement register handling for exec'd inferiors. 8050b57cec5SDimitry Andric // if (tid_stop_info.reason == eStopReasonExec) { 8060b57cec5SDimitry Andric // const bool force = true; 8070b57cec5SDimitry Andric // InitializeRegisters(force); 8080b57cec5SDimitry Andric // } 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric // Output the T packet with the thread 8110b57cec5SDimitry Andric response.PutChar('T'); 81281ad6265SDimitry Andric int signum = tid_stop_info.signo; 8130b57cec5SDimitry Andric LLDB_LOG( 8140b57cec5SDimitry Andric log, 8150b57cec5SDimitry Andric "pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}", 81681ad6265SDimitry Andric process.GetID(), thread.GetID(), signum, int(tid_stop_info.reason), 8170b57cec5SDimitry Andric tid_stop_info.details.exception.type); 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric // Print the signal number. 8200b57cec5SDimitry Andric response.PutHex8(signum & 0xff); 8210b57cec5SDimitry Andric 82281ad6265SDimitry Andric // Include the (pid and) tid. 82381ad6265SDimitry Andric response.PutCString("thread:"); 82481ad6265SDimitry Andric AppendThreadIDToResponse(response, process.GetID(), thread.GetID()); 82581ad6265SDimitry Andric response.PutChar(';'); 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric // Include the thread name if there is one. 82881ad6265SDimitry Andric const std::string thread_name = thread.GetName(); 8290b57cec5SDimitry Andric if (!thread_name.empty()) { 8300b57cec5SDimitry Andric size_t thread_name_len = thread_name.length(); 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric if (::strcspn(thread_name.c_str(), "$#+-;:") == thread_name_len) { 8330b57cec5SDimitry Andric response.PutCString("name:"); 8340b57cec5SDimitry Andric response.PutCString(thread_name); 8350b57cec5SDimitry Andric } else { 8360b57cec5SDimitry Andric // The thread name contains special chars, send as hex bytes. 8370b57cec5SDimitry Andric response.PutCString("hexname:"); 8380b57cec5SDimitry Andric response.PutStringAsRawHex8(thread_name); 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric response.PutChar(';'); 8410b57cec5SDimitry Andric } 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andric // If a 'QListThreadsInStopReply' was sent to enable this feature, we will 8440b57cec5SDimitry Andric // send all thread IDs back in the "threads" key whose value is a list of hex 8450b57cec5SDimitry Andric // thread IDs separated by commas: 8460b57cec5SDimitry Andric // "threads:10a,10b,10c;" 8470b57cec5SDimitry Andric // This will save the debugger from having to send a pair of qfThreadInfo and 8480b57cec5SDimitry Andric // qsThreadInfo packets, but it also might take a lot of room in the stop 8490b57cec5SDimitry Andric // reply packet, so it must be enabled only on systems where there are no 8500b57cec5SDimitry Andric // limits on packet lengths. 8510b57cec5SDimitry Andric if (m_list_threads_in_stop_reply) { 8520b57cec5SDimitry Andric response.PutCString("threads:"); 8530b57cec5SDimitry Andric 85481ad6265SDimitry Andric uint32_t thread_num = 0; 85581ad6265SDimitry Andric for (NativeThreadProtocol &listed_thread : process.Threads()) { 85681ad6265SDimitry Andric if (thread_num > 0) 8570b57cec5SDimitry Andric response.PutChar(','); 85881ad6265SDimitry Andric response.Printf("%" PRIx64, listed_thread.GetID()); 85981ad6265SDimitry Andric ++thread_num; 8600b57cec5SDimitry Andric } 8610b57cec5SDimitry Andric response.PutChar(';'); 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric // Include JSON info that describes the stop reason for any threads that 8640b57cec5SDimitry Andric // actually have stop reasons. We use the new "jstopinfo" key whose values 8650b57cec5SDimitry Andric // is hex ascii JSON that contains the thread IDs thread stop info only for 8660b57cec5SDimitry Andric // threads that have stop reasons. Only send this if we have more than one 8670b57cec5SDimitry Andric // thread otherwise this packet has all the info it needs. 86881ad6265SDimitry Andric if (thread_num > 1) { 8690b57cec5SDimitry Andric const bool threads_with_valid_stop_info_only = true; 8709dba64beSDimitry Andric llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo( 871fe6060f1SDimitry Andric *m_current_process, threads_with_valid_stop_info_only); 8729dba64beSDimitry Andric if (threads_info) { 8730b57cec5SDimitry Andric response.PutCString("jstopinfo:"); 8740b57cec5SDimitry Andric StreamString unescaped_response; 8759dba64beSDimitry Andric unescaped_response.AsRawOstream() << std::move(*threads_info); 8760b57cec5SDimitry Andric response.PutStringAsRawHex8(unescaped_response.GetData()); 8770b57cec5SDimitry Andric response.PutChar(';'); 8789dba64beSDimitry Andric } else { 879480093f4SDimitry Andric LLDB_LOG_ERROR(log, threads_info.takeError(), 880480093f4SDimitry Andric "failed to prepare a jstopinfo field for pid {1}: {0}", 88181ad6265SDimitry Andric process.GetID()); 8829dba64beSDimitry Andric } 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric 8850b57cec5SDimitry Andric response.PutCString("thread-pcs"); 8860b57cec5SDimitry Andric char delimiter = ':'; 88781ad6265SDimitry Andric for (NativeThreadProtocol &thread : process.Threads()) { 88881ad6265SDimitry Andric NativeRegisterContext ®_ctx = thread.GetRegisterContext(); 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber( 8910b57cec5SDimitry Andric eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 8920b57cec5SDimitry Andric const RegisterInfo *const reg_info_p = 8930b57cec5SDimitry Andric reg_ctx.GetRegisterInfoAtIndex(reg_to_read); 8940b57cec5SDimitry Andric 8950b57cec5SDimitry Andric RegisterValue reg_value; 8960b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); 8970b57cec5SDimitry Andric if (error.Fail()) { 8989dba64beSDimitry Andric LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s", 8990b57cec5SDimitry Andric __FUNCTION__, 9009dba64beSDimitry Andric reg_info_p->name ? reg_info_p->name : "<unnamed-register>", 9010b57cec5SDimitry Andric reg_to_read, error.AsCString()); 9020b57cec5SDimitry Andric continue; 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric response.PutChar(delimiter); 9060b57cec5SDimitry Andric delimiter = ','; 9070b57cec5SDimitry Andric WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p, 9080b57cec5SDimitry Andric ®_value, endian::InlHostByteOrder()); 9090b57cec5SDimitry Andric } 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric response.PutChar(';'); 9120b57cec5SDimitry Andric } 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric // 9150b57cec5SDimitry Andric // Expedite registers. 9160b57cec5SDimitry Andric // 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric // Grab the register context. 91981ad6265SDimitry Andric NativeRegisterContext ®_ctx = thread.GetRegisterContext(); 920e8d8bef9SDimitry Andric const auto expedited_regs = 921e8d8bef9SDimitry Andric reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full); 9220b57cec5SDimitry Andric 923e8d8bef9SDimitry Andric for (auto ®_num : expedited_regs) { 9240b57cec5SDimitry Andric const RegisterInfo *const reg_info_p = 925e8d8bef9SDimitry Andric reg_ctx.GetRegisterInfoAtIndex(reg_num); 9260b57cec5SDimitry Andric // Only expediate registers that are not contained in other registers. 927e8d8bef9SDimitry Andric if (reg_info_p != nullptr && reg_info_p->value_regs == nullptr) { 9280b57cec5SDimitry Andric RegisterValue reg_value; 9290b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); 9300b57cec5SDimitry Andric if (error.Success()) { 931e8d8bef9SDimitry Andric response.Printf("%.02x:", reg_num); 9320b57cec5SDimitry Andric WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p, 9330b57cec5SDimitry Andric ®_value, lldb::eByteOrderBig); 9340b57cec5SDimitry Andric response.PutChar(';'); 9350b57cec5SDimitry Andric } else { 93681ad6265SDimitry Andric LLDB_LOGF(log, 93781ad6265SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to read " 9380b57cec5SDimitry Andric "register '%s' index %" PRIu32 ": %s", 9390b57cec5SDimitry Andric __FUNCTION__, 9409dba64beSDimitry Andric reg_info_p->name ? reg_info_p->name : "<unnamed-register>", 941e8d8bef9SDimitry Andric reg_num, error.AsCString()); 9420b57cec5SDimitry Andric } 9430b57cec5SDimitry Andric } 9440b57cec5SDimitry Andric } 9450b57cec5SDimitry Andric 9460b57cec5SDimitry Andric const char *reason_str = GetStopReasonString(tid_stop_info.reason); 9470b57cec5SDimitry Andric if (reason_str != nullptr) { 9480b57cec5SDimitry Andric response.Printf("reason:%s;", reason_str); 9490b57cec5SDimitry Andric } 9500b57cec5SDimitry Andric 9510b57cec5SDimitry Andric if (!description.empty()) { 9520b57cec5SDimitry Andric // Description may contains special chars, send as hex bytes. 9530b57cec5SDimitry Andric response.PutCString("description:"); 9540b57cec5SDimitry Andric response.PutStringAsRawHex8(description); 9550b57cec5SDimitry Andric response.PutChar(';'); 9560b57cec5SDimitry Andric } else if ((tid_stop_info.reason == eStopReasonException) && 9570b57cec5SDimitry Andric tid_stop_info.details.exception.type) { 9580b57cec5SDimitry Andric response.PutCString("metype:"); 9590b57cec5SDimitry Andric response.PutHex64(tid_stop_info.details.exception.type); 9600b57cec5SDimitry Andric response.PutCString(";mecount:"); 9610b57cec5SDimitry Andric response.PutHex32(tid_stop_info.details.exception.data_count); 9620b57cec5SDimitry Andric response.PutChar(';'); 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andric for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) { 9650b57cec5SDimitry Andric response.PutCString("medata:"); 9660b57cec5SDimitry Andric response.PutHex64(tid_stop_info.details.exception.data[i]); 9670b57cec5SDimitry Andric response.PutChar(';'); 9680b57cec5SDimitry Andric } 9690b57cec5SDimitry Andric } 9700b57cec5SDimitry Andric 971fe6060f1SDimitry Andric // Include child process PID/TID for forks. 972fe6060f1SDimitry Andric if (tid_stop_info.reason == eStopReasonFork || 973fe6060f1SDimitry Andric tid_stop_info.reason == eStopReasonVFork) { 974fe6060f1SDimitry Andric assert(bool(m_extensions_supported & 975fe6060f1SDimitry Andric NativeProcessProtocol::Extension::multiprocess)); 976fe6060f1SDimitry Andric if (tid_stop_info.reason == eStopReasonFork) 977fe6060f1SDimitry Andric assert(bool(m_extensions_supported & 978fe6060f1SDimitry Andric NativeProcessProtocol::Extension::fork)); 979fe6060f1SDimitry Andric if (tid_stop_info.reason == eStopReasonVFork) 980fe6060f1SDimitry Andric assert(bool(m_extensions_supported & 981fe6060f1SDimitry Andric NativeProcessProtocol::Extension::vfork)); 982fe6060f1SDimitry Andric response.Printf("%s:p%" PRIx64 ".%" PRIx64 ";", reason_str, 983fe6060f1SDimitry Andric tid_stop_info.details.fork.child_pid, 984fe6060f1SDimitry Andric tid_stop_info.details.fork.child_tid); 985fe6060f1SDimitry Andric } 986fe6060f1SDimitry Andric 98781ad6265SDimitry Andric return response; 98881ad6265SDimitry Andric } 98981ad6265SDimitry Andric 99081ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 99181ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( 99281ad6265SDimitry Andric NativeProcessProtocol &process, lldb::tid_t tid, bool force_synchronous) { 99381ad6265SDimitry Andric // Ensure we can get info on the given thread. 99481ad6265SDimitry Andric NativeThreadProtocol *thread = process.GetThreadByID(tid); 99581ad6265SDimitry Andric if (!thread) 99681ad6265SDimitry Andric return SendErrorResponse(51); 99781ad6265SDimitry Andric 99881ad6265SDimitry Andric StreamString response = PrepareStopReplyPacketForThread(*thread); 99981ad6265SDimitry Andric if (response.Empty()) 100081ad6265SDimitry Andric return SendErrorResponse(42); 100181ad6265SDimitry Andric 100281ad6265SDimitry Andric if (m_non_stop && !force_synchronous) { 100381ad6265SDimitry Andric PacketResult ret = SendNotificationPacketNoLock( 100481ad6265SDimitry Andric "Stop", m_stop_notification_queue, response.GetString()); 100581ad6265SDimitry Andric // Queue notification events for the remaining threads. 100681ad6265SDimitry Andric EnqueueStopReplyPackets(tid); 100781ad6265SDimitry Andric return ret; 100881ad6265SDimitry Andric } 100981ad6265SDimitry Andric 10100b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 10110b57cec5SDimitry Andric } 10120b57cec5SDimitry Andric 101381ad6265SDimitry Andric void GDBRemoteCommunicationServerLLGS::EnqueueStopReplyPackets( 101481ad6265SDimitry Andric lldb::tid_t thread_to_skip) { 101581ad6265SDimitry Andric if (!m_non_stop) 101681ad6265SDimitry Andric return; 101781ad6265SDimitry Andric 101881ad6265SDimitry Andric for (NativeThreadProtocol &listed_thread : m_current_process->Threads()) { 101981ad6265SDimitry Andric if (listed_thread.GetID() != thread_to_skip) 102081ad6265SDimitry Andric m_stop_notification_queue.push_back( 102181ad6265SDimitry Andric PrepareStopReplyPacketForThread(listed_thread).GetString().str()); 102281ad6265SDimitry Andric } 102381ad6265SDimitry Andric } 102481ad6265SDimitry Andric 10250b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( 10260b57cec5SDimitry Andric NativeProcessProtocol *process) { 10270b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 10280b57cec5SDimitry Andric 102981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 10309dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); 10310b57cec5SDimitry Andric 103281ad6265SDimitry Andric PacketResult result = SendStopReasonForState( 103381ad6265SDimitry Andric *process, StateType::eStateExited, /*force_synchronous=*/false); 10340b57cec5SDimitry Andric if (result != PacketResult::Success) { 10359dba64beSDimitry Andric LLDB_LOGF(log, 10369dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to send stop " 10370b57cec5SDimitry Andric "notification for PID %" PRIu64 ", state: eStateExited", 10380b57cec5SDimitry Andric __FUNCTION__, process->GetID()); 10390b57cec5SDimitry Andric } 10400b57cec5SDimitry Andric 104181ad6265SDimitry Andric if (m_current_process == process) 104281ad6265SDimitry Andric m_current_process = nullptr; 104381ad6265SDimitry Andric if (m_continue_process == process) 104481ad6265SDimitry Andric m_continue_process = nullptr; 104581ad6265SDimitry Andric 104681ad6265SDimitry Andric lldb::pid_t pid = process->GetID(); 104781ad6265SDimitry Andric m_mainloop.AddPendingCallback([this, pid](MainLoopBase &loop) { 104881ad6265SDimitry Andric m_debugged_processes.erase(pid); 104981ad6265SDimitry Andric auto vkill_it = m_vkilled_processes.find(pid); 105081ad6265SDimitry Andric if (vkill_it != m_vkilled_processes.end()) 105181ad6265SDimitry Andric m_vkilled_processes.erase(vkill_it); 105281ad6265SDimitry Andric // Terminate the main loop only if vKill has not been used. 105381ad6265SDimitry Andric // When running in non-stop mode, wait for the vStopped to clear 105481ad6265SDimitry Andric // the notification queue. 105581ad6265SDimitry Andric else if (m_debugged_processes.empty() && !m_non_stop) { 105681ad6265SDimitry Andric // Close the pipe to the inferior terminal i/o if we launched it and set 105781ad6265SDimitry Andric // one up. 10580b57cec5SDimitry Andric MaybeCloseInferiorTerminalConnection(); 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric // We are ready to exit the debug monitor. 10610b57cec5SDimitry Andric m_exit_now = true; 106281ad6265SDimitry Andric loop.RequestTermination(); 106381ad6265SDimitry Andric } 106481ad6265SDimitry Andric }); 10650b57cec5SDimitry Andric } 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( 10680b57cec5SDimitry Andric NativeProcessProtocol *process) { 10690b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 10700b57cec5SDimitry Andric 107181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 10729dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric // Send the stop reason unless this is the stop after the launch or attach. 10750b57cec5SDimitry Andric switch (m_inferior_prev_state) { 10760b57cec5SDimitry Andric case eStateLaunching: 10770b57cec5SDimitry Andric case eStateAttaching: 10780b57cec5SDimitry Andric // Don't send anything per debugserver behavior. 10790b57cec5SDimitry Andric break; 10800b57cec5SDimitry Andric default: 10810b57cec5SDimitry Andric // In all other cases, send the stop reason. 108281ad6265SDimitry Andric PacketResult result = SendStopReasonForState( 108381ad6265SDimitry Andric *process, StateType::eStateStopped, /*force_synchronous=*/false); 10840b57cec5SDimitry Andric if (result != PacketResult::Success) { 10859dba64beSDimitry Andric LLDB_LOGF(log, 10869dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to send stop " 10870b57cec5SDimitry Andric "notification for PID %" PRIu64 ", state: eStateExited", 10880b57cec5SDimitry Andric __FUNCTION__, process->GetID()); 10890b57cec5SDimitry Andric } 10900b57cec5SDimitry Andric break; 10910b57cec5SDimitry Andric } 10920b57cec5SDimitry Andric } 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::ProcessStateChanged( 10950b57cec5SDimitry Andric NativeProcessProtocol *process, lldb::StateType state) { 10960b57cec5SDimitry Andric assert(process && "process cannot be NULL"); 109781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 10980b57cec5SDimitry Andric if (log) { 10999dba64beSDimitry Andric LLDB_LOGF(log, 11009dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s called with " 11010b57cec5SDimitry Andric "NativeProcessProtocol pid %" PRIu64 ", state: %s", 11020b57cec5SDimitry Andric __FUNCTION__, process->GetID(), StateAsCString(state)); 11030b57cec5SDimitry Andric } 11040b57cec5SDimitry Andric 11050b57cec5SDimitry Andric switch (state) { 11060b57cec5SDimitry Andric case StateType::eStateRunning: 11070b57cec5SDimitry Andric break; 11080b57cec5SDimitry Andric 11090b57cec5SDimitry Andric case StateType::eStateStopped: 11100b57cec5SDimitry Andric // Make sure we get all of the pending stdout/stderr from the inferior and 11110b57cec5SDimitry Andric // send it to the lldb host before we send the state change notification 11120b57cec5SDimitry Andric SendProcessOutput(); 11130b57cec5SDimitry Andric // Then stop the forwarding, so that any late output (see llvm.org/pr25652) 11140b57cec5SDimitry Andric // does not interfere with our protocol. 11150b57cec5SDimitry Andric StopSTDIOForwarding(); 11160b57cec5SDimitry Andric HandleInferiorState_Stopped(process); 11170b57cec5SDimitry Andric break; 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric case StateType::eStateExited: 11200b57cec5SDimitry Andric // Same as above 11210b57cec5SDimitry Andric SendProcessOutput(); 11220b57cec5SDimitry Andric StopSTDIOForwarding(); 11230b57cec5SDimitry Andric HandleInferiorState_Exited(process); 11240b57cec5SDimitry Andric break; 11250b57cec5SDimitry Andric 11260b57cec5SDimitry Andric default: 11270b57cec5SDimitry Andric if (log) { 11289dba64beSDimitry Andric LLDB_LOGF(log, 11299dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s didn't handle state " 11300b57cec5SDimitry Andric "change for pid %" PRIu64 ", new state: %s", 11310b57cec5SDimitry Andric __FUNCTION__, process->GetID(), StateAsCString(state)); 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric break; 11340b57cec5SDimitry Andric } 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric // Remember the previous state reported to us. 11370b57cec5SDimitry Andric m_inferior_prev_state = state; 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()); 1150fe6060f1SDimitry Andric m_debugged_processes[child_pid] = std::move(child_process); 1151fe6060f1SDimitry Andric } 1152fe6060f1SDimitry Andric 11530b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() { 115404eeddc0SDimitry Andric Log *log = GetLog(GDBRLog::Comm); 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andric bool interrupt = false; 11570b57cec5SDimitry Andric bool done = false; 11580b57cec5SDimitry Andric Status error; 11590b57cec5SDimitry Andric while (true) { 11600b57cec5SDimitry Andric const PacketResult result = GetPacketAndSendResponse( 11610b57cec5SDimitry Andric std::chrono::microseconds(0), error, interrupt, done); 11620b57cec5SDimitry Andric if (result == PacketResult::ErrorReplyTimeout) 11630b57cec5SDimitry Andric break; // No more packets in the queue 11640b57cec5SDimitry Andric 11650b57cec5SDimitry Andric if ((result != PacketResult::Success)) { 11669dba64beSDimitry Andric LLDB_LOGF(log, 11679dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s processing a packet " 11680b57cec5SDimitry Andric "failed: %s", 11690b57cec5SDimitry Andric __FUNCTION__, error.AsCString()); 11700b57cec5SDimitry Andric m_mainloop.RequestTermination(); 11710b57cec5SDimitry Andric break; 11720b57cec5SDimitry Andric } 11730b57cec5SDimitry Andric } 11740b57cec5SDimitry Andric } 11750b57cec5SDimitry Andric 11760b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::InitializeConnection( 11775ffd83dbSDimitry Andric std::unique_ptr<Connection> connection) { 11780b57cec5SDimitry Andric IOObjectSP read_object_sp = connection->GetReadObject(); 11795ffd83dbSDimitry Andric GDBRemoteCommunicationServer::SetConnection(std::move(connection)); 11800b57cec5SDimitry Andric 11810b57cec5SDimitry Andric Status error; 11820b57cec5SDimitry Andric m_network_handle_up = m_mainloop.RegisterReadObject( 11830b57cec5SDimitry Andric read_object_sp, [this](MainLoopBase &) { DataAvailableCallback(); }, 11840b57cec5SDimitry Andric error); 11850b57cec5SDimitry Andric return error; 11860b57cec5SDimitry Andric } 11870b57cec5SDimitry Andric 11880b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 11890b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer, 11900b57cec5SDimitry Andric uint32_t len) { 11910b57cec5SDimitry Andric if ((buffer == nullptr) || (len == 0)) { 11920b57cec5SDimitry Andric // Nothing to send. 11930b57cec5SDimitry Andric return PacketResult::Success; 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric StreamString response; 11970b57cec5SDimitry Andric response.PutChar('O'); 11980b57cec5SDimitry Andric response.PutBytesAsRawHex8(buffer, len); 11990b57cec5SDimitry Andric 12000b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 12010b57cec5SDimitry Andric } 12020b57cec5SDimitry Andric 12030b57cec5SDimitry Andric Status GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) { 12040b57cec5SDimitry Andric Status error; 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric // Set up the reading/handling of process I/O 12070b57cec5SDimitry Andric std::unique_ptr<ConnectionFileDescriptor> conn_up( 12080b57cec5SDimitry Andric new ConnectionFileDescriptor(fd, true)); 12090b57cec5SDimitry Andric if (!conn_up) { 12100b57cec5SDimitry Andric error.SetErrorString("failed to create ConnectionFileDescriptor"); 12110b57cec5SDimitry Andric return error; 12120b57cec5SDimitry Andric } 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andric m_stdio_communication.SetCloseOnEOF(false); 12155ffd83dbSDimitry Andric m_stdio_communication.SetConnection(std::move(conn_up)); 12160b57cec5SDimitry Andric if (!m_stdio_communication.IsConnected()) { 12170b57cec5SDimitry Andric error.SetErrorString( 12180b57cec5SDimitry Andric "failed to set connection for inferior I/O communication"); 12190b57cec5SDimitry Andric return error; 12200b57cec5SDimitry Andric } 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric return Status(); 12230b57cec5SDimitry Andric } 12240b57cec5SDimitry Andric 12250b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() { 12260b57cec5SDimitry Andric // Don't forward if not connected (e.g. when attaching). 12270b57cec5SDimitry Andric if (!m_stdio_communication.IsConnected()) 12280b57cec5SDimitry Andric return; 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric Status error; 123181ad6265SDimitry Andric assert(!m_stdio_handle_up); 12320b57cec5SDimitry Andric m_stdio_handle_up = m_mainloop.RegisterReadObject( 12330b57cec5SDimitry Andric m_stdio_communication.GetConnection()->GetReadObject(), 12340b57cec5SDimitry Andric [this](MainLoopBase &) { SendProcessOutput(); }, error); 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andric if (!m_stdio_handle_up) { 12370b57cec5SDimitry Andric // Not much we can do about the failure. Log it and continue without 12380b57cec5SDimitry Andric // forwarding. 123981ad6265SDimitry Andric if (Log *log = GetLog(LLDBLog::Process)) 124081ad6265SDimitry Andric LLDB_LOG(log, "Failed to set up stdio forwarding: {0}", error); 12410b57cec5SDimitry Andric } 12420b57cec5SDimitry Andric } 12430b57cec5SDimitry Andric 12440b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() { 12450b57cec5SDimitry Andric m_stdio_handle_up.reset(); 12460b57cec5SDimitry Andric } 12470b57cec5SDimitry Andric 12480b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SendProcessOutput() { 12490b57cec5SDimitry Andric char buffer[1024]; 12500b57cec5SDimitry Andric ConnectionStatus status; 12510b57cec5SDimitry Andric Status error; 12520b57cec5SDimitry Andric while (true) { 12530b57cec5SDimitry Andric size_t bytes_read = m_stdio_communication.Read( 12540b57cec5SDimitry Andric buffer, sizeof buffer, std::chrono::microseconds(0), status, &error); 12550b57cec5SDimitry Andric switch (status) { 12560b57cec5SDimitry Andric case eConnectionStatusSuccess: 12570b57cec5SDimitry Andric SendONotification(buffer, bytes_read); 12580b57cec5SDimitry Andric break; 12590b57cec5SDimitry Andric case eConnectionStatusLostConnection: 12600b57cec5SDimitry Andric case eConnectionStatusEndOfFile: 12610b57cec5SDimitry Andric case eConnectionStatusError: 12620b57cec5SDimitry Andric case eConnectionStatusNoConnection: 126381ad6265SDimitry Andric if (Log *log = GetLog(LLDBLog::Process)) 12649dba64beSDimitry Andric LLDB_LOGF(log, 12659dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s Stopping stdio " 12660b57cec5SDimitry Andric "forwarding as communication returned status %d (error: " 12670b57cec5SDimitry Andric "%s)", 12680b57cec5SDimitry Andric __FUNCTION__, status, error.AsCString()); 12690b57cec5SDimitry Andric m_stdio_handle_up.reset(); 12700b57cec5SDimitry Andric return; 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andric case eConnectionStatusInterrupted: 12730b57cec5SDimitry Andric case eConnectionStatusTimedOut: 12740b57cec5SDimitry Andric return; 12750b57cec5SDimitry Andric } 12760b57cec5SDimitry Andric } 12770b57cec5SDimitry Andric } 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1280fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported( 12810b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 1282fe6060f1SDimitry Andric 12830b57cec5SDimitry Andric // Fail if we don't have a current process. 1284fe6060f1SDimitry Andric if (!m_current_process || 1285fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 1286fe6060f1SDimitry Andric return SendErrorResponse(Status("Process not running.")); 12870b57cec5SDimitry Andric 1288fe6060f1SDimitry Andric return SendJSONResponse(m_current_process->TraceSupported()); 12890b57cec5SDimitry Andric } 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1292fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop( 12930b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 12940b57cec5SDimitry Andric // Fail if we don't have a current process. 1295fe6060f1SDimitry Andric if (!m_current_process || 1296fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 1297fe6060f1SDimitry Andric return SendErrorResponse(Status("Process not running.")); 12980b57cec5SDimitry Andric 1299fe6060f1SDimitry Andric packet.ConsumeFront("jLLDBTraceStop:"); 1300fe6060f1SDimitry Andric Expected<TraceStopRequest> stop_request = 1301fe6060f1SDimitry Andric json::parse<TraceStopRequest>(packet.Peek(), "TraceStopRequest"); 1302fe6060f1SDimitry Andric if (!stop_request) 1303fe6060f1SDimitry Andric return SendErrorResponse(stop_request.takeError()); 13040b57cec5SDimitry Andric 1305fe6060f1SDimitry Andric if (Error err = m_current_process->TraceStop(*stop_request)) 1306fe6060f1SDimitry Andric return SendErrorResponse(std::move(err)); 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andric return SendOKResponse(); 13090b57cec5SDimitry Andric } 13100b57cec5SDimitry Andric 13110b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1312fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart( 1313e8d8bef9SDimitry Andric StringExtractorGDBRemote &packet) { 1314e8d8bef9SDimitry Andric 1315e8d8bef9SDimitry Andric // Fail if we don't have a current process. 1316fe6060f1SDimitry Andric if (!m_current_process || 1317fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 1318e8d8bef9SDimitry Andric return SendErrorResponse(Status("Process not running.")); 1319e8d8bef9SDimitry Andric 1320fe6060f1SDimitry Andric packet.ConsumeFront("jLLDBTraceStart:"); 1321fe6060f1SDimitry Andric Expected<TraceStartRequest> request = 1322fe6060f1SDimitry Andric json::parse<TraceStartRequest>(packet.Peek(), "TraceStartRequest"); 1323fe6060f1SDimitry Andric if (!request) 1324fe6060f1SDimitry Andric return SendErrorResponse(request.takeError()); 1325e8d8bef9SDimitry Andric 1326fe6060f1SDimitry Andric if (Error err = m_current_process->TraceStart(packet.Peek(), request->type)) 1327fe6060f1SDimitry Andric return SendErrorResponse(std::move(err)); 1328e8d8bef9SDimitry Andric 1329fe6060f1SDimitry Andric return SendOKResponse(); 1330e8d8bef9SDimitry Andric } 1331e8d8bef9SDimitry Andric 1332e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 1333fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState( 13340b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 13350b57cec5SDimitry Andric 13360b57cec5SDimitry Andric // Fail if we don't have a current process. 1337fe6060f1SDimitry Andric if (!m_current_process || 1338fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 1339fe6060f1SDimitry Andric return SendErrorResponse(Status("Process not running.")); 13400b57cec5SDimitry Andric 1341fe6060f1SDimitry Andric packet.ConsumeFront("jLLDBTraceGetState:"); 1342fe6060f1SDimitry Andric Expected<TraceGetStateRequest> request = 1343fe6060f1SDimitry Andric json::parse<TraceGetStateRequest>(packet.Peek(), "TraceGetStateRequest"); 1344fe6060f1SDimitry Andric if (!request) 1345fe6060f1SDimitry Andric return SendErrorResponse(request.takeError()); 13460b57cec5SDimitry Andric 1347fe6060f1SDimitry Andric return SendJSONResponse(m_current_process->TraceGetState(request->type)); 13480b57cec5SDimitry Andric } 13490b57cec5SDimitry Andric 13500b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1351fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData( 13520b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 13530b57cec5SDimitry Andric 13540b57cec5SDimitry Andric // Fail if we don't have a current process. 1355fe6060f1SDimitry Andric if (!m_current_process || 1356fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 1357fe6060f1SDimitry Andric return SendErrorResponse(Status("Process not running.")); 13580b57cec5SDimitry Andric 1359fe6060f1SDimitry Andric packet.ConsumeFront("jLLDBTraceGetBinaryData:"); 1360fe6060f1SDimitry Andric llvm::Expected<TraceGetBinaryDataRequest> request = 1361fe6060f1SDimitry Andric llvm::json::parse<TraceGetBinaryDataRequest>(packet.Peek(), 1362fe6060f1SDimitry Andric "TraceGetBinaryDataRequest"); 1363fe6060f1SDimitry Andric if (!request) 1364fe6060f1SDimitry Andric return SendErrorResponse(Status(request.takeError())); 13650b57cec5SDimitry Andric 1366fe6060f1SDimitry Andric if (Expected<std::vector<uint8_t>> bytes = 1367fe6060f1SDimitry Andric m_current_process->TraceGetBinaryData(*request)) { 13680b57cec5SDimitry Andric StreamGDBRemote response; 1369fe6060f1SDimitry Andric response.PutEscapedBytes(bytes->data(), bytes->size()); 1370fe6060f1SDimitry Andric return SendPacketNoLock(response.GetString()); 1371fe6060f1SDimitry Andric } else 1372fe6060f1SDimitry Andric return SendErrorResponse(bytes.takeError()); 13730b57cec5SDimitry Andric } 13740b57cec5SDimitry Andric 13750b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 13760b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo( 13770b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 13780b57cec5SDimitry Andric // Fail if we don't have a current process. 1379fe6060f1SDimitry Andric if (!m_current_process || 1380fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 13810b57cec5SDimitry Andric return SendErrorResponse(68); 13820b57cec5SDimitry Andric 1383fe6060f1SDimitry Andric lldb::pid_t pid = m_current_process->GetID(); 13840b57cec5SDimitry Andric 13850b57cec5SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 13860b57cec5SDimitry Andric return SendErrorResponse(1); 13870b57cec5SDimitry Andric 13880b57cec5SDimitry Andric ProcessInstanceInfo proc_info; 13890b57cec5SDimitry Andric if (!Host::GetProcessInfo(pid, proc_info)) 13900b57cec5SDimitry Andric return SendErrorResponse(1); 13910b57cec5SDimitry Andric 13920b57cec5SDimitry Andric StreamString response; 13930b57cec5SDimitry Andric CreateProcessInfoResponse_DebugServerStyle(proc_info, response); 13940b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 13950b57cec5SDimitry Andric } 13960b57cec5SDimitry Andric 13970b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 13980b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) { 13990b57cec5SDimitry Andric // Fail if we don't have a current process. 1400fe6060f1SDimitry Andric if (!m_current_process || 1401fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 14020b57cec5SDimitry Andric return SendErrorResponse(68); 14030b57cec5SDimitry Andric 14040b57cec5SDimitry Andric // Make sure we set the current thread so g and p packets return the data the 14050b57cec5SDimitry Andric // gdb will expect. 1406fe6060f1SDimitry Andric lldb::tid_t tid = m_current_process->GetCurrentThreadID(); 14070b57cec5SDimitry Andric SetCurrentThreadID(tid); 14080b57cec5SDimitry Andric 1409fe6060f1SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); 14100b57cec5SDimitry Andric if (!thread) 14110b57cec5SDimitry Andric return SendErrorResponse(69); 14120b57cec5SDimitry Andric 14130b57cec5SDimitry Andric StreamString response; 141481ad6265SDimitry Andric response.PutCString("QC"); 141581ad6265SDimitry Andric AppendThreadIDToResponse(response, m_current_process->GetID(), 141681ad6265SDimitry Andric thread->GetID()); 14170b57cec5SDimitry Andric 14180b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 14190b57cec5SDimitry Andric } 14200b57cec5SDimitry Andric 14210b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 14220b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) { 142381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 14240b57cec5SDimitry Andric 14250b57cec5SDimitry Andric StopSTDIOForwarding(); 14260b57cec5SDimitry Andric 142781ad6265SDimitry Andric if (m_debugged_processes.empty()) { 14280b57cec5SDimitry Andric LLDB_LOG(log, "No debugged process found."); 14290b57cec5SDimitry Andric return PacketResult::Success; 14300b57cec5SDimitry Andric } 14310b57cec5SDimitry Andric 143281ad6265SDimitry Andric for (auto it = m_debugged_processes.begin(); it != m_debugged_processes.end(); 143381ad6265SDimitry Andric ++it) { 143481ad6265SDimitry Andric LLDB_LOG(log, "Killing process {0}", it->first); 143581ad6265SDimitry Andric Status error = it->second->Kill(); 14360b57cec5SDimitry Andric if (error.Fail()) 143781ad6265SDimitry Andric LLDB_LOG(log, "Failed to kill debugged process {0}: {1}", it->first, 143881ad6265SDimitry Andric error); 143981ad6265SDimitry Andric } 14400b57cec5SDimitry Andric 144181ad6265SDimitry Andric // The response to kill packet is undefined per the spec. LLDB 144281ad6265SDimitry Andric // follows the same rules as for continue packets, i.e. no response 144381ad6265SDimitry Andric // in all-stop mode, and "OK" in non-stop mode; in both cases this 144481ad6265SDimitry Andric // is followed by the actual stop reason. 144581ad6265SDimitry Andric return SendContinueSuccessResponse(); 144681ad6265SDimitry Andric } 144781ad6265SDimitry Andric 144881ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 144981ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vKill( 145081ad6265SDimitry Andric StringExtractorGDBRemote &packet) { 145181ad6265SDimitry Andric StopSTDIOForwarding(); 145281ad6265SDimitry Andric 145381ad6265SDimitry Andric packet.SetFilePos(6); // vKill; 145481ad6265SDimitry Andric uint32_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); 145581ad6265SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 145681ad6265SDimitry Andric return SendIllFormedResponse(packet, 145781ad6265SDimitry Andric "vKill failed to parse the process id"); 145881ad6265SDimitry Andric 145981ad6265SDimitry Andric auto it = m_debugged_processes.find(pid); 146081ad6265SDimitry Andric if (it == m_debugged_processes.end()) 146181ad6265SDimitry Andric return SendErrorResponse(42); 146281ad6265SDimitry Andric 146381ad6265SDimitry Andric Status error = it->second->Kill(); 146481ad6265SDimitry Andric if (error.Fail()) 146581ad6265SDimitry Andric return SendErrorResponse(error.ToError()); 146681ad6265SDimitry Andric 146781ad6265SDimitry Andric // OK response is sent when the process dies. 146881ad6265SDimitry Andric m_vkilled_processes.insert(pid); 14690b57cec5SDimitry Andric return PacketResult::Success; 14700b57cec5SDimitry Andric } 14710b57cec5SDimitry Andric 14720b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 14730b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR( 14740b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 14750b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetDisableASLR:")); 14760b57cec5SDimitry Andric if (packet.GetU32(0)) 14770b57cec5SDimitry Andric m_process_launch_info.GetFlags().Set(eLaunchFlagDisableASLR); 14780b57cec5SDimitry Andric else 14790b57cec5SDimitry Andric m_process_launch_info.GetFlags().Clear(eLaunchFlagDisableASLR); 14800b57cec5SDimitry Andric return SendOKResponse(); 14810b57cec5SDimitry Andric } 14820b57cec5SDimitry Andric 14830b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 14840b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir( 14850b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 14860b57cec5SDimitry Andric packet.SetFilePos(::strlen("QSetWorkingDir:")); 14870b57cec5SDimitry Andric std::string path; 14880b57cec5SDimitry Andric packet.GetHexByteString(path); 14890b57cec5SDimitry Andric m_process_launch_info.SetWorkingDirectory(FileSpec(path)); 14900b57cec5SDimitry Andric return SendOKResponse(); 14910b57cec5SDimitry Andric } 14920b57cec5SDimitry Andric 14930b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 14940b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir( 14950b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 14960b57cec5SDimitry Andric FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()}; 14970b57cec5SDimitry Andric if (working_dir) { 14980b57cec5SDimitry Andric StreamString response; 14990b57cec5SDimitry Andric response.PutStringAsRawHex8(working_dir.GetCString()); 15000b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 15010b57cec5SDimitry Andric } 15020b57cec5SDimitry Andric 15030b57cec5SDimitry Andric return SendErrorResponse(14); 15040b57cec5SDimitry Andric } 15050b57cec5SDimitry Andric 15060b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 1507fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported( 1508fe6060f1SDimitry Andric StringExtractorGDBRemote &packet) { 1509fe6060f1SDimitry Andric m_thread_suffix_supported = true; 1510fe6060f1SDimitry Andric return SendOKResponse(); 1511fe6060f1SDimitry Andric } 1512fe6060f1SDimitry Andric 1513fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult 1514fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply( 1515fe6060f1SDimitry Andric StringExtractorGDBRemote &packet) { 1516fe6060f1SDimitry Andric m_list_threads_in_stop_reply = true; 1517fe6060f1SDimitry Andric return SendOKResponse(); 1518fe6060f1SDimitry Andric } 1519fe6060f1SDimitry Andric 1520fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult 15210b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { 152281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 15239dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); 15240b57cec5SDimitry Andric 15250b57cec5SDimitry Andric // Ensure we have a native process. 1526fe6060f1SDimitry Andric if (!m_continue_process) { 15279dba64beSDimitry Andric LLDB_LOGF(log, 15289dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s no debugged process " 15290b57cec5SDimitry Andric "shared pointer", 15300b57cec5SDimitry Andric __FUNCTION__); 15310b57cec5SDimitry Andric return SendErrorResponse(0x36); 15320b57cec5SDimitry Andric } 15330b57cec5SDimitry Andric 15340b57cec5SDimitry Andric // Pull out the signal number. 15350b57cec5SDimitry Andric packet.SetFilePos(::strlen("C")); 15360b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) { 15370b57cec5SDimitry Andric // Shouldn't be using a C without a signal. 15380b57cec5SDimitry Andric return SendIllFormedResponse(packet, "C packet specified without signal."); 15390b57cec5SDimitry Andric } 15400b57cec5SDimitry Andric const uint32_t signo = 15410b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 15420b57cec5SDimitry Andric if (signo == std::numeric_limits<uint32_t>::max()) 15430b57cec5SDimitry Andric return SendIllFormedResponse(packet, "failed to parse signal number"); 15440b57cec5SDimitry Andric 15450b57cec5SDimitry Andric // Handle optional continue address. 15460b57cec5SDimitry Andric if (packet.GetBytesLeft() > 0) { 15470b57cec5SDimitry Andric // FIXME add continue at address support for $C{signo}[;{continue-address}]. 15480b57cec5SDimitry Andric if (*packet.Peek() == ';') 15499dba64beSDimitry Andric return SendUnimplementedResponse(packet.GetStringRef().data()); 15500b57cec5SDimitry Andric else 15510b57cec5SDimitry Andric return SendIllFormedResponse( 15520b57cec5SDimitry Andric packet, "unexpected content after $C{signal-number}"); 15530b57cec5SDimitry Andric } 15540b57cec5SDimitry Andric 15559dba64beSDimitry Andric ResumeActionList resume_actions(StateType::eStateRunning, 15569dba64beSDimitry Andric LLDB_INVALID_SIGNAL_NUMBER); 15570b57cec5SDimitry Andric Status error; 15580b57cec5SDimitry Andric 15590b57cec5SDimitry Andric // We have two branches: what to do if a continue thread is specified (in 15600b57cec5SDimitry Andric // which case we target sending the signal to that thread), or when we don't 15610b57cec5SDimitry Andric // have a continue thread set (in which case we send a signal to the 15620b57cec5SDimitry Andric // process). 15630b57cec5SDimitry Andric 15640b57cec5SDimitry Andric // TODO discuss with Greg Clayton, make sure this makes sense. 15650b57cec5SDimitry Andric 15660b57cec5SDimitry Andric lldb::tid_t signal_tid = GetContinueThreadID(); 15670b57cec5SDimitry Andric if (signal_tid != LLDB_INVALID_THREAD_ID) { 15680b57cec5SDimitry Andric // The resume action for the continue thread (or all threads if a continue 15690b57cec5SDimitry Andric // thread is not set). 15700b57cec5SDimitry Andric ResumeAction action = {GetContinueThreadID(), StateType::eStateRunning, 15710b57cec5SDimitry Andric static_cast<int>(signo)}; 15720b57cec5SDimitry Andric 15730b57cec5SDimitry Andric // Add the action for the continue thread (or all threads when the continue 15740b57cec5SDimitry Andric // thread isn't present). 15750b57cec5SDimitry Andric resume_actions.Append(action); 15760b57cec5SDimitry Andric } else { 15770b57cec5SDimitry Andric // Send the signal to the process since we weren't targeting a specific 15780b57cec5SDimitry Andric // continue thread with the signal. 1579fe6060f1SDimitry Andric error = m_continue_process->Signal(signo); 15800b57cec5SDimitry Andric if (error.Fail()) { 15810b57cec5SDimitry Andric LLDB_LOG(log, "failed to send signal for process {0}: {1}", 1582fe6060f1SDimitry Andric m_continue_process->GetID(), error); 15830b57cec5SDimitry Andric 15840b57cec5SDimitry Andric return SendErrorResponse(0x52); 15850b57cec5SDimitry Andric } 15860b57cec5SDimitry Andric } 15870b57cec5SDimitry Andric 15880b57cec5SDimitry Andric // Resume the threads. 1589fe6060f1SDimitry Andric error = m_continue_process->Resume(resume_actions); 15900b57cec5SDimitry Andric if (error.Fail()) { 15910b57cec5SDimitry Andric LLDB_LOG(log, "failed to resume threads for process {0}: {1}", 1592fe6060f1SDimitry Andric m_continue_process->GetID(), error); 15930b57cec5SDimitry Andric 15940b57cec5SDimitry Andric return SendErrorResponse(0x38); 15950b57cec5SDimitry Andric } 15960b57cec5SDimitry Andric 159781ad6265SDimitry Andric // Don't send an "OK" packet, except in non-stop mode; 159881ad6265SDimitry Andric // otherwise, the response is the stopped/exited message. 159981ad6265SDimitry Andric return SendContinueSuccessResponse(); 16000b57cec5SDimitry Andric } 16010b57cec5SDimitry Andric 16020b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 16030b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) { 160481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 16059dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); 16060b57cec5SDimitry Andric 16070b57cec5SDimitry Andric packet.SetFilePos(packet.GetFilePos() + ::strlen("c")); 16080b57cec5SDimitry Andric 16090b57cec5SDimitry Andric // For now just support all continue. 16100b57cec5SDimitry Andric const bool has_continue_address = (packet.GetBytesLeft() > 0); 16110b57cec5SDimitry Andric if (has_continue_address) { 16120b57cec5SDimitry Andric LLDB_LOG(log, "not implemented for c[address] variant [{0} remains]", 16130b57cec5SDimitry Andric packet.Peek()); 16149dba64beSDimitry Andric return SendUnimplementedResponse(packet.GetStringRef().data()); 16150b57cec5SDimitry Andric } 16160b57cec5SDimitry Andric 16170b57cec5SDimitry Andric // Ensure we have a native process. 1618fe6060f1SDimitry Andric if (!m_continue_process) { 16199dba64beSDimitry Andric LLDB_LOGF(log, 16209dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s no debugged process " 16210b57cec5SDimitry Andric "shared pointer", 16220b57cec5SDimitry Andric __FUNCTION__); 16230b57cec5SDimitry Andric return SendErrorResponse(0x36); 16240b57cec5SDimitry Andric } 16250b57cec5SDimitry Andric 16260b57cec5SDimitry Andric // Build the ResumeActionList 16279dba64beSDimitry Andric ResumeActionList actions(StateType::eStateRunning, 16289dba64beSDimitry Andric LLDB_INVALID_SIGNAL_NUMBER); 16290b57cec5SDimitry Andric 1630fe6060f1SDimitry Andric Status error = m_continue_process->Resume(actions); 16310b57cec5SDimitry Andric if (error.Fail()) { 1632fe6060f1SDimitry Andric LLDB_LOG(log, "c failed for process {0}: {1}", m_continue_process->GetID(), 1633fe6060f1SDimitry Andric error); 16340b57cec5SDimitry Andric return SendErrorResponse(GDBRemoteServerError::eErrorResume); 16350b57cec5SDimitry Andric } 16360b57cec5SDimitry Andric 1637fe6060f1SDimitry Andric LLDB_LOG(log, "continued process {0}", m_continue_process->GetID()); 163881ad6265SDimitry Andric 163981ad6265SDimitry Andric return SendContinueSuccessResponse(); 16400b57cec5SDimitry Andric } 16410b57cec5SDimitry Andric 16420b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 16430b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vCont_actions( 16440b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 16450b57cec5SDimitry Andric StreamString response; 164681ad6265SDimitry Andric response.Printf("vCont;c;C;s;S;t"); 16470b57cec5SDimitry Andric 16480b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 16490b57cec5SDimitry Andric } 16500b57cec5SDimitry Andric 16510b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 16520b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vCont( 16530b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 165481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 16559dba64beSDimitry Andric LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s handling vCont packet", 16560b57cec5SDimitry Andric __FUNCTION__); 16570b57cec5SDimitry Andric 16580b57cec5SDimitry Andric packet.SetFilePos(::strlen("vCont")); 16590b57cec5SDimitry Andric 16600b57cec5SDimitry Andric if (packet.GetBytesLeft() == 0) { 16619dba64beSDimitry Andric LLDB_LOGF(log, 16629dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s missing action from " 16630b57cec5SDimitry Andric "vCont package", 16640b57cec5SDimitry Andric __FUNCTION__); 16650b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Missing action from vCont package"); 16660b57cec5SDimitry Andric } 16670b57cec5SDimitry Andric 166881ad6265SDimitry Andric if (::strcmp(packet.Peek(), ";s") == 0) { 16690b57cec5SDimitry Andric // Move past the ';', then do a simple 's'. 16700b57cec5SDimitry Andric packet.SetFilePos(packet.GetFilePos() + 1); 16710b57cec5SDimitry Andric return Handle_s(packet); 167281ad6265SDimitry Andric } else if (m_non_stop && ::strcmp(packet.Peek(), ";t") == 0) { 167381ad6265SDimitry Andric // TODO: add full support for "t" action 167481ad6265SDimitry Andric return SendOKResponse(); 16750b57cec5SDimitry Andric } 16760b57cec5SDimitry Andric 167781ad6265SDimitry Andric std::unordered_map<lldb::pid_t, ResumeActionList> thread_actions; 16780b57cec5SDimitry Andric 16790b57cec5SDimitry Andric while (packet.GetBytesLeft() && *packet.Peek() == ';') { 16800b57cec5SDimitry Andric // Skip the semi-colon. 16810b57cec5SDimitry Andric packet.GetChar(); 16820b57cec5SDimitry Andric 16830b57cec5SDimitry Andric // Build up the thread action. 16840b57cec5SDimitry Andric ResumeAction thread_action; 16850b57cec5SDimitry Andric thread_action.tid = LLDB_INVALID_THREAD_ID; 16860b57cec5SDimitry Andric thread_action.state = eStateInvalid; 16879dba64beSDimitry Andric thread_action.signal = LLDB_INVALID_SIGNAL_NUMBER; 16880b57cec5SDimitry Andric 16890b57cec5SDimitry Andric const char action = packet.GetChar(); 16900b57cec5SDimitry Andric switch (action) { 16910b57cec5SDimitry Andric case 'C': 16920b57cec5SDimitry Andric thread_action.signal = packet.GetHexMaxU32(false, 0); 16930b57cec5SDimitry Andric if (thread_action.signal == 0) 16940b57cec5SDimitry Andric return SendIllFormedResponse( 16950b57cec5SDimitry Andric packet, "Could not parse signal in vCont packet C action"); 16960b57cec5SDimitry Andric LLVM_FALLTHROUGH; 16970b57cec5SDimitry Andric 16980b57cec5SDimitry Andric case 'c': 16990b57cec5SDimitry Andric // Continue 17000b57cec5SDimitry Andric thread_action.state = eStateRunning; 17010b57cec5SDimitry Andric break; 17020b57cec5SDimitry Andric 17030b57cec5SDimitry Andric case 'S': 17040b57cec5SDimitry Andric thread_action.signal = packet.GetHexMaxU32(false, 0); 17050b57cec5SDimitry Andric if (thread_action.signal == 0) 17060b57cec5SDimitry Andric return SendIllFormedResponse( 17070b57cec5SDimitry Andric packet, "Could not parse signal in vCont packet S action"); 17080b57cec5SDimitry Andric LLVM_FALLTHROUGH; 17090b57cec5SDimitry Andric 17100b57cec5SDimitry Andric case 's': 17110b57cec5SDimitry Andric // Step 17120b57cec5SDimitry Andric thread_action.state = eStateStepping; 17130b57cec5SDimitry Andric break; 17140b57cec5SDimitry Andric 171581ad6265SDimitry Andric case 't': 171681ad6265SDimitry Andric // Stop 171781ad6265SDimitry Andric thread_action.state = eStateSuspended; 171881ad6265SDimitry Andric break; 171981ad6265SDimitry Andric 17200b57cec5SDimitry Andric default: 17210b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Unsupported vCont action"); 17220b57cec5SDimitry Andric break; 17230b57cec5SDimitry Andric } 17240b57cec5SDimitry Andric 172581ad6265SDimitry Andric lldb::pid_t pid = StringExtractorGDBRemote::AllProcesses; 172681ad6265SDimitry Andric lldb::tid_t tid = StringExtractorGDBRemote::AllThreads; 172781ad6265SDimitry Andric 17280b57cec5SDimitry Andric // Parse out optional :{thread-id} value. 17290b57cec5SDimitry Andric if (packet.GetBytesLeft() && (*packet.Peek() == ':')) { 17300b57cec5SDimitry Andric // Consume the separator. 17310b57cec5SDimitry Andric packet.GetChar(); 17320b57cec5SDimitry Andric 173381ad6265SDimitry Andric auto pid_tid = packet.GetPidTid(StringExtractorGDBRemote::AllProcesses); 173481ad6265SDimitry Andric if (!pid_tid) 173581ad6265SDimitry Andric return SendIllFormedResponse(packet, "Malformed thread-id"); 1736fe6060f1SDimitry Andric 173781ad6265SDimitry Andric pid = pid_tid->first; 173881ad6265SDimitry Andric tid = pid_tid->second; 17390b57cec5SDimitry Andric } 17400b57cec5SDimitry Andric 174181ad6265SDimitry Andric if (pid == StringExtractorGDBRemote::AllProcesses) { 174281ad6265SDimitry Andric if (m_debugged_processes.size() > 1) 174381ad6265SDimitry Andric return SendIllFormedResponse( 174481ad6265SDimitry Andric packet, "Resuming multiple processes not supported yet"); 174581ad6265SDimitry Andric if (!m_continue_process) { 174681ad6265SDimitry Andric LLDB_LOG(log, "no debugged process"); 174781ad6265SDimitry Andric return SendErrorResponse(0x36); 174881ad6265SDimitry Andric } 174981ad6265SDimitry Andric pid = m_continue_process->GetID(); 17500b57cec5SDimitry Andric } 17510b57cec5SDimitry Andric 175281ad6265SDimitry Andric if (tid == StringExtractorGDBRemote::AllThreads) 175381ad6265SDimitry Andric tid = LLDB_INVALID_THREAD_ID; 175481ad6265SDimitry Andric 175581ad6265SDimitry Andric thread_action.tid = tid; 175681ad6265SDimitry Andric 175781ad6265SDimitry Andric thread_actions[pid].Append(thread_action); 175881ad6265SDimitry Andric } 175981ad6265SDimitry Andric 176081ad6265SDimitry Andric assert(thread_actions.size() >= 1); 176181ad6265SDimitry Andric if (thread_actions.size() > 1) 176281ad6265SDimitry Andric return SendIllFormedResponse( 176381ad6265SDimitry Andric packet, "Resuming multiple processes not supported yet"); 176481ad6265SDimitry Andric 176581ad6265SDimitry Andric for (std::pair<lldb::pid_t, ResumeActionList> x : thread_actions) { 176681ad6265SDimitry Andric auto process_it = m_debugged_processes.find(x.first); 176781ad6265SDimitry Andric if (process_it == m_debugged_processes.end()) { 176881ad6265SDimitry Andric LLDB_LOG(log, "vCont failed for process {0}: process not debugged", 176981ad6265SDimitry Andric x.first); 17700b57cec5SDimitry Andric return SendErrorResponse(GDBRemoteServerError::eErrorResume); 17710b57cec5SDimitry Andric } 17720b57cec5SDimitry Andric 177381ad6265SDimitry Andric Status error = process_it->second->Resume(x.second); 177481ad6265SDimitry Andric if (error.Fail()) { 177581ad6265SDimitry Andric LLDB_LOG(log, "vCont failed for process {0}: {1}", x.first, error); 177681ad6265SDimitry Andric return SendErrorResponse(GDBRemoteServerError::eErrorResume); 177781ad6265SDimitry Andric } 177881ad6265SDimitry Andric 177981ad6265SDimitry Andric LLDB_LOG(log, "continued process {0}", x.first); 178081ad6265SDimitry Andric } 178181ad6265SDimitry Andric 178281ad6265SDimitry Andric return SendContinueSuccessResponse(); 17830b57cec5SDimitry Andric } 17840b57cec5SDimitry Andric 17850b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) { 178681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 17870b57cec5SDimitry Andric LLDB_LOG(log, "setting current thread id to {0}", tid); 17880b57cec5SDimitry Andric 17890b57cec5SDimitry Andric m_current_tid = tid; 1790fe6060f1SDimitry Andric if (m_current_process) 1791fe6060f1SDimitry Andric m_current_process->SetCurrentThreadID(m_current_tid); 17920b57cec5SDimitry Andric } 17930b57cec5SDimitry Andric 17940b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) { 179581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 17960b57cec5SDimitry Andric LLDB_LOG(log, "setting continue thread id to {0}", tid); 17970b57cec5SDimitry Andric 17980b57cec5SDimitry Andric m_continue_tid = tid; 17990b57cec5SDimitry Andric } 18000b57cec5SDimitry Andric 18010b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 18020b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_stop_reason( 18030b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 18040b57cec5SDimitry Andric // Handle the $? gdbremote command. 18050b57cec5SDimitry Andric 180681ad6265SDimitry Andric if (m_non_stop) { 180781ad6265SDimitry Andric // Clear the notification queue first, except for pending exit 180881ad6265SDimitry Andric // notifications. 180981ad6265SDimitry Andric llvm::erase_if(m_stop_notification_queue, [](const std::string &x) { 181081ad6265SDimitry Andric return x.front() != 'W' && x.front() != 'X'; 181181ad6265SDimitry Andric }); 181281ad6265SDimitry Andric 181381ad6265SDimitry Andric if (m_current_process) { 181481ad6265SDimitry Andric // Queue stop reply packets for all active threads. Start with 181581ad6265SDimitry Andric // the current thread (for clients that don't actually support multiple 181681ad6265SDimitry Andric // stop reasons). 181781ad6265SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); 181881ad6265SDimitry Andric if (thread) 181981ad6265SDimitry Andric m_stop_notification_queue.push_back( 182081ad6265SDimitry Andric PrepareStopReplyPacketForThread(*thread).GetString().str()); 182181ad6265SDimitry Andric EnqueueStopReplyPackets(thread ? thread->GetID() 182281ad6265SDimitry Andric : LLDB_INVALID_THREAD_ID); 182381ad6265SDimitry Andric } 182481ad6265SDimitry Andric 182581ad6265SDimitry Andric // If the notification queue is empty (i.e. everything is running), send OK. 182681ad6265SDimitry Andric if (m_stop_notification_queue.empty()) 182781ad6265SDimitry Andric return SendOKResponse(); 182881ad6265SDimitry Andric 182981ad6265SDimitry Andric // Send the first item from the new notification queue synchronously. 183081ad6265SDimitry Andric return SendPacketNoLock(m_stop_notification_queue.front()); 183181ad6265SDimitry Andric } 183281ad6265SDimitry Andric 18330b57cec5SDimitry Andric // If no process, indicate error 1834fe6060f1SDimitry Andric if (!m_current_process) 18350b57cec5SDimitry Andric return SendErrorResponse(02); 18360b57cec5SDimitry Andric 183781ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 183881ad6265SDimitry Andric m_current_process->GetState(), 183981ad6265SDimitry Andric /*force_synchronous=*/true); 18400b57cec5SDimitry Andric } 18410b57cec5SDimitry Andric 18420b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 18430b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::SendStopReasonForState( 184481ad6265SDimitry Andric NativeProcessProtocol &process, lldb::StateType process_state, 184581ad6265SDimitry Andric bool force_synchronous) { 184681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 18470b57cec5SDimitry Andric 18480b57cec5SDimitry Andric switch (process_state) { 18490b57cec5SDimitry Andric case eStateAttaching: 18500b57cec5SDimitry Andric case eStateLaunching: 18510b57cec5SDimitry Andric case eStateRunning: 18520b57cec5SDimitry Andric case eStateStepping: 18530b57cec5SDimitry Andric case eStateDetached: 18540b57cec5SDimitry Andric // NOTE: gdb protocol doc looks like it should return $OK 18550b57cec5SDimitry Andric // when everything is running (i.e. no stopped result). 18560b57cec5SDimitry Andric return PacketResult::Success; // Ignore 18570b57cec5SDimitry Andric 18580b57cec5SDimitry Andric case eStateSuspended: 18590b57cec5SDimitry Andric case eStateStopped: 18600b57cec5SDimitry Andric case eStateCrashed: { 186181ad6265SDimitry Andric lldb::tid_t tid = process.GetCurrentThreadID(); 18620b57cec5SDimitry Andric // Make sure we set the current thread so g and p packets return the data 18630b57cec5SDimitry Andric // the gdb will expect. 18640b57cec5SDimitry Andric SetCurrentThreadID(tid); 186581ad6265SDimitry Andric return SendStopReplyPacketForThread(process, tid, force_synchronous); 18660b57cec5SDimitry Andric } 18670b57cec5SDimitry Andric 18680b57cec5SDimitry Andric case eStateInvalid: 18690b57cec5SDimitry Andric case eStateUnloaded: 18700b57cec5SDimitry Andric case eStateExited: 187181ad6265SDimitry Andric return SendWResponse(&process); 18720b57cec5SDimitry Andric 18730b57cec5SDimitry Andric default: 18740b57cec5SDimitry Andric LLDB_LOG(log, "pid {0}, current state reporting not handled: {1}", 187581ad6265SDimitry Andric process.GetID(), process_state); 18760b57cec5SDimitry Andric break; 18770b57cec5SDimitry Andric } 18780b57cec5SDimitry Andric 18790b57cec5SDimitry Andric return SendErrorResponse(0); 18800b57cec5SDimitry Andric } 18810b57cec5SDimitry Andric 18820b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 18830b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( 18840b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 18850b57cec5SDimitry Andric // Fail if we don't have a current process. 1886fe6060f1SDimitry Andric if (!m_current_process || 1887fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 18880b57cec5SDimitry Andric return SendErrorResponse(68); 18890b57cec5SDimitry Andric 18900b57cec5SDimitry Andric // Ensure we have a thread. 1891fe6060f1SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0); 18920b57cec5SDimitry Andric if (!thread) 18930b57cec5SDimitry Andric return SendErrorResponse(69); 18940b57cec5SDimitry Andric 18950b57cec5SDimitry Andric // Get the register context for the first thread. 18960b57cec5SDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 18970b57cec5SDimitry Andric 18980b57cec5SDimitry Andric // Parse out the register number from the request. 18990b57cec5SDimitry Andric packet.SetFilePos(strlen("qRegisterInfo")); 19000b57cec5SDimitry Andric const uint32_t reg_index = 19010b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 19020b57cec5SDimitry Andric if (reg_index == std::numeric_limits<uint32_t>::max()) 19030b57cec5SDimitry Andric return SendErrorResponse(69); 19040b57cec5SDimitry Andric 19050b57cec5SDimitry Andric // Return the end of registers response if we've iterated one past the end of 19060b57cec5SDimitry Andric // the register set. 19070b57cec5SDimitry Andric if (reg_index >= reg_context.GetUserRegisterCount()) 19080b57cec5SDimitry Andric return SendErrorResponse(69); 19090b57cec5SDimitry Andric 19100b57cec5SDimitry Andric const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); 19110b57cec5SDimitry Andric if (!reg_info) 19120b57cec5SDimitry Andric return SendErrorResponse(69); 19130b57cec5SDimitry Andric 19140b57cec5SDimitry Andric // Build the reginfos response. 19150b57cec5SDimitry Andric StreamGDBRemote response; 19160b57cec5SDimitry Andric 19170b57cec5SDimitry Andric response.PutCString("name:"); 19180b57cec5SDimitry Andric response.PutCString(reg_info->name); 19190b57cec5SDimitry Andric response.PutChar(';'); 19200b57cec5SDimitry Andric 19210b57cec5SDimitry Andric if (reg_info->alt_name && reg_info->alt_name[0]) { 19220b57cec5SDimitry Andric response.PutCString("alt-name:"); 19230b57cec5SDimitry Andric response.PutCString(reg_info->alt_name); 19240b57cec5SDimitry Andric response.PutChar(';'); 19250b57cec5SDimitry Andric } 19260b57cec5SDimitry Andric 1927e8d8bef9SDimitry Andric response.Printf("bitsize:%" PRIu32 ";", reg_info->byte_size * 8); 1928e8d8bef9SDimitry Andric 1929e8d8bef9SDimitry Andric if (!reg_context.RegisterOffsetIsDynamic()) 1930e8d8bef9SDimitry Andric response.Printf("offset:%" PRIu32 ";", reg_info->byte_offset); 19310b57cec5SDimitry Andric 19325ffd83dbSDimitry Andric llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info); 19335ffd83dbSDimitry Andric if (!encoding.empty()) 19345ffd83dbSDimitry Andric response << "encoding:" << encoding << ';'; 19350b57cec5SDimitry Andric 19365ffd83dbSDimitry Andric llvm::StringRef format = GetFormatNameOrEmpty(*reg_info); 19375ffd83dbSDimitry Andric if (!format.empty()) 19385ffd83dbSDimitry Andric response << "format:" << format << ';'; 19390b57cec5SDimitry Andric 19400b57cec5SDimitry Andric const char *const register_set_name = 19410b57cec5SDimitry Andric reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); 19425ffd83dbSDimitry Andric if (register_set_name) 19435ffd83dbSDimitry Andric response << "set:" << register_set_name << ';'; 19440b57cec5SDimitry Andric 19450b57cec5SDimitry Andric if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != 19460b57cec5SDimitry Andric LLDB_INVALID_REGNUM) 19470b57cec5SDimitry Andric response.Printf("ehframe:%" PRIu32 ";", 19480b57cec5SDimitry Andric reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); 19490b57cec5SDimitry Andric 19500b57cec5SDimitry Andric if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM) 19510b57cec5SDimitry Andric response.Printf("dwarf:%" PRIu32 ";", 19520b57cec5SDimitry Andric reg_info->kinds[RegisterKind::eRegisterKindDWARF]); 19530b57cec5SDimitry Andric 19545ffd83dbSDimitry Andric llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info); 19555ffd83dbSDimitry Andric if (!kind_generic.empty()) 19565ffd83dbSDimitry Andric response << "generic:" << kind_generic << ';'; 19570b57cec5SDimitry Andric 19580b57cec5SDimitry Andric if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { 19590b57cec5SDimitry Andric response.PutCString("container-regs:"); 19605ffd83dbSDimitry Andric CollectRegNums(reg_info->value_regs, response, true); 19610b57cec5SDimitry Andric response.PutChar(';'); 19620b57cec5SDimitry Andric } 19630b57cec5SDimitry Andric 19640b57cec5SDimitry Andric if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { 19650b57cec5SDimitry Andric response.PutCString("invalidate-regs:"); 19665ffd83dbSDimitry Andric CollectRegNums(reg_info->invalidate_regs, response, true); 19670b57cec5SDimitry Andric response.PutChar(';'); 19680b57cec5SDimitry Andric } 19690b57cec5SDimitry Andric 19700b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 19710b57cec5SDimitry Andric } 19720b57cec5SDimitry Andric 197381ad6265SDimitry Andric void GDBRemoteCommunicationServerLLGS::AddProcessThreads( 197481ad6265SDimitry Andric StreamGDBRemote &response, NativeProcessProtocol &process, bool &had_any) { 197581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 197681ad6265SDimitry Andric 197781ad6265SDimitry Andric lldb::pid_t pid = process.GetID(); 197881ad6265SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 197981ad6265SDimitry Andric return; 198081ad6265SDimitry Andric 198181ad6265SDimitry Andric LLDB_LOG(log, "iterating over threads of process {0}", process.GetID()); 198281ad6265SDimitry Andric for (NativeThreadProtocol &thread : process.Threads()) { 198381ad6265SDimitry Andric LLDB_LOG(log, "iterated thread tid={0}", thread.GetID()); 198481ad6265SDimitry Andric response.PutChar(had_any ? ',' : 'm'); 198581ad6265SDimitry Andric AppendThreadIDToResponse(response, pid, thread.GetID()); 198681ad6265SDimitry Andric had_any = true; 198781ad6265SDimitry Andric } 198881ad6265SDimitry Andric } 198981ad6265SDimitry Andric 19900b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 19910b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo( 19920b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 199381ad6265SDimitry Andric assert(m_debugged_processes.size() == 1 || 199481ad6265SDimitry Andric bool(m_extensions_supported & 199581ad6265SDimitry Andric NativeProcessProtocol::Extension::multiprocess)); 19960b57cec5SDimitry Andric 199781ad6265SDimitry Andric bool had_any = false; 19980b57cec5SDimitry Andric StreamGDBRemote response; 19990b57cec5SDimitry Andric 200081ad6265SDimitry Andric for (auto &pid_ptr : m_debugged_processes) 200181ad6265SDimitry Andric AddProcessThreads(response, *pid_ptr.second, had_any); 20020b57cec5SDimitry Andric 200381ad6265SDimitry Andric if (!had_any) 200481ad6265SDimitry Andric return SendOKResponse(); 20050b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 20060b57cec5SDimitry Andric } 20070b57cec5SDimitry Andric 20080b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 20090b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo( 20100b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 20110b57cec5SDimitry Andric // FIXME for now we return the full thread list in the initial packet and 20120b57cec5SDimitry Andric // always do nothing here. 20130b57cec5SDimitry Andric return SendPacketNoLock("l"); 20140b57cec5SDimitry Andric } 20150b57cec5SDimitry Andric 20160b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 20170b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) { 201881ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 20190b57cec5SDimitry Andric 20200b57cec5SDimitry Andric // Move past packet name. 20210b57cec5SDimitry Andric packet.SetFilePos(strlen("g")); 20220b57cec5SDimitry Andric 20230b57cec5SDimitry Andric // Get the thread to use. 20240b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 20250b57cec5SDimitry Andric if (!thread) { 20260b57cec5SDimitry Andric LLDB_LOG(log, "failed, no thread available"); 20270b57cec5SDimitry Andric return SendErrorResponse(0x15); 20280b57cec5SDimitry Andric } 20290b57cec5SDimitry Andric 20300b57cec5SDimitry Andric // Get the thread's register context. 20310b57cec5SDimitry Andric NativeRegisterContext ®_ctx = thread->GetRegisterContext(); 20320b57cec5SDimitry Andric 20330b57cec5SDimitry Andric std::vector<uint8_t> regs_buffer; 20340b57cec5SDimitry Andric for (uint32_t reg_num = 0; reg_num < reg_ctx.GetUserRegisterCount(); 20350b57cec5SDimitry Andric ++reg_num) { 20360b57cec5SDimitry Andric const RegisterInfo *reg_info = reg_ctx.GetRegisterInfoAtIndex(reg_num); 20370b57cec5SDimitry Andric 20380b57cec5SDimitry Andric if (reg_info == nullptr) { 20390b57cec5SDimitry Andric LLDB_LOG(log, "failed to get register info for register index {0}", 20400b57cec5SDimitry Andric reg_num); 20410b57cec5SDimitry Andric return SendErrorResponse(0x15); 20420b57cec5SDimitry Andric } 20430b57cec5SDimitry Andric 20440b57cec5SDimitry Andric if (reg_info->value_regs != nullptr) 20450b57cec5SDimitry Andric continue; // skip registers that are contained in other registers 20460b57cec5SDimitry Andric 20470b57cec5SDimitry Andric RegisterValue reg_value; 20480b57cec5SDimitry Andric Status error = reg_ctx.ReadRegister(reg_info, reg_value); 20490b57cec5SDimitry Andric if (error.Fail()) { 20500b57cec5SDimitry Andric LLDB_LOG(log, "failed to read register at index {0}", reg_num); 20510b57cec5SDimitry Andric return SendErrorResponse(0x15); 20520b57cec5SDimitry Andric } 20530b57cec5SDimitry Andric 20540b57cec5SDimitry Andric if (reg_info->byte_offset + reg_info->byte_size >= regs_buffer.size()) 20550b57cec5SDimitry Andric // Resize the buffer to guarantee it can store the register offsetted 20560b57cec5SDimitry Andric // data. 20570b57cec5SDimitry Andric regs_buffer.resize(reg_info->byte_offset + reg_info->byte_size); 20580b57cec5SDimitry Andric 20590b57cec5SDimitry Andric // Copy the register offsetted data to the buffer. 20600b57cec5SDimitry Andric memcpy(regs_buffer.data() + reg_info->byte_offset, reg_value.GetBytes(), 20610b57cec5SDimitry Andric reg_info->byte_size); 20620b57cec5SDimitry Andric } 20630b57cec5SDimitry Andric 20640b57cec5SDimitry Andric // Write the response. 20650b57cec5SDimitry Andric StreamGDBRemote response; 20660b57cec5SDimitry Andric response.PutBytesAsRawHex8(regs_buffer.data(), regs_buffer.size()); 20670b57cec5SDimitry Andric 20680b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 20690b57cec5SDimitry Andric } 20700b57cec5SDimitry Andric 20710b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 20720b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { 207381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 20740b57cec5SDimitry Andric 20750b57cec5SDimitry Andric // Parse out the register number from the request. 20760b57cec5SDimitry Andric packet.SetFilePos(strlen("p")); 20770b57cec5SDimitry Andric const uint32_t reg_index = 20780b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 20790b57cec5SDimitry Andric if (reg_index == std::numeric_limits<uint32_t>::max()) { 20809dba64beSDimitry Andric LLDB_LOGF(log, 20819dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, could not " 20820b57cec5SDimitry Andric "parse register number from request \"%s\"", 20839dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 20840b57cec5SDimitry Andric return SendErrorResponse(0x15); 20850b57cec5SDimitry Andric } 20860b57cec5SDimitry Andric 20870b57cec5SDimitry Andric // Get the thread to use. 20880b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 20890b57cec5SDimitry Andric if (!thread) { 20900b57cec5SDimitry Andric LLDB_LOG(log, "failed, no thread available"); 20910b57cec5SDimitry Andric return SendErrorResponse(0x15); 20920b57cec5SDimitry Andric } 20930b57cec5SDimitry Andric 20940b57cec5SDimitry Andric // Get the thread's register context. 20950b57cec5SDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 20960b57cec5SDimitry Andric 20970b57cec5SDimitry Andric // Return the end of registers response if we've iterated one past the end of 20980b57cec5SDimitry Andric // the register set. 20990b57cec5SDimitry Andric if (reg_index >= reg_context.GetUserRegisterCount()) { 21009dba64beSDimitry Andric LLDB_LOGF(log, 21019dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, requested " 21020b57cec5SDimitry Andric "register %" PRIu32 " beyond register count %" PRIu32, 21039dba64beSDimitry Andric __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); 21040b57cec5SDimitry Andric return SendErrorResponse(0x15); 21050b57cec5SDimitry Andric } 21060b57cec5SDimitry Andric 21070b57cec5SDimitry Andric const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); 21080b57cec5SDimitry Andric if (!reg_info) { 21099dba64beSDimitry Andric LLDB_LOGF(log, 21109dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, requested " 21110b57cec5SDimitry Andric "register %" PRIu32 " returned NULL", 21120b57cec5SDimitry Andric __FUNCTION__, reg_index); 21130b57cec5SDimitry Andric return SendErrorResponse(0x15); 21140b57cec5SDimitry Andric } 21150b57cec5SDimitry Andric 21160b57cec5SDimitry Andric // Build the reginfos response. 21170b57cec5SDimitry Andric StreamGDBRemote response; 21180b57cec5SDimitry Andric 21190b57cec5SDimitry Andric // Retrieve the value 21200b57cec5SDimitry Andric RegisterValue reg_value; 21210b57cec5SDimitry Andric Status error = reg_context.ReadRegister(reg_info, reg_value); 21220b57cec5SDimitry Andric if (error.Fail()) { 21239dba64beSDimitry Andric LLDB_LOGF(log, 21249dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, read of " 21250b57cec5SDimitry Andric "requested register %" PRIu32 " (%s) failed: %s", 21260b57cec5SDimitry Andric __FUNCTION__, reg_index, reg_info->name, error.AsCString()); 21270b57cec5SDimitry Andric return SendErrorResponse(0x15); 21280b57cec5SDimitry Andric } 21290b57cec5SDimitry Andric 21300b57cec5SDimitry Andric const uint8_t *const data = 2131480093f4SDimitry Andric static_cast<const uint8_t *>(reg_value.GetBytes()); 21320b57cec5SDimitry Andric if (!data) { 21339dba64beSDimitry Andric LLDB_LOGF(log, 21349dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to get data " 21350b57cec5SDimitry Andric "bytes from requested register %" PRIu32, 21360b57cec5SDimitry Andric __FUNCTION__, reg_index); 21370b57cec5SDimitry Andric return SendErrorResponse(0x15); 21380b57cec5SDimitry Andric } 21390b57cec5SDimitry Andric 21400b57cec5SDimitry Andric // FIXME flip as needed to get data in big/little endian format for this host. 21410b57cec5SDimitry Andric for (uint32_t i = 0; i < reg_value.GetByteSize(); ++i) 21420b57cec5SDimitry Andric response.PutHex8(data[i]); 21430b57cec5SDimitry Andric 21440b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 21450b57cec5SDimitry Andric } 21460b57cec5SDimitry Andric 21470b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 21480b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { 214981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 21500b57cec5SDimitry Andric 21510b57cec5SDimitry Andric // Ensure there is more content. 21520b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 21530b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Empty P packet"); 21540b57cec5SDimitry Andric 21550b57cec5SDimitry Andric // Parse out the register number from the request. 21560b57cec5SDimitry Andric packet.SetFilePos(strlen("P")); 21570b57cec5SDimitry Andric const uint32_t reg_index = 21580b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 21590b57cec5SDimitry Andric if (reg_index == std::numeric_limits<uint32_t>::max()) { 21609dba64beSDimitry Andric LLDB_LOGF(log, 21619dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, could not " 21620b57cec5SDimitry Andric "parse register number from request \"%s\"", 21639dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 21640b57cec5SDimitry Andric return SendErrorResponse(0x29); 21650b57cec5SDimitry Andric } 21660b57cec5SDimitry Andric 21670b57cec5SDimitry Andric // Note debugserver would send an E30 here. 21680b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != '=')) 21690b57cec5SDimitry Andric return SendIllFormedResponse( 21700b57cec5SDimitry Andric packet, "P packet missing '=' char after register number"); 21710b57cec5SDimitry Andric 21720b57cec5SDimitry Andric // Parse out the value. 21735ffd83dbSDimitry Andric uint8_t reg_bytes[RegisterValue::kMaxRegisterByteSize]; 21740b57cec5SDimitry Andric size_t reg_size = packet.GetHexBytesAvail(reg_bytes); 21750b57cec5SDimitry Andric 21760b57cec5SDimitry Andric // Get the thread to use. 21770b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 21780b57cec5SDimitry Andric if (!thread) { 21799dba64beSDimitry Andric LLDB_LOGF(log, 21809dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no thread " 21810b57cec5SDimitry Andric "available (thread index 0)", 21820b57cec5SDimitry Andric __FUNCTION__); 21830b57cec5SDimitry Andric return SendErrorResponse(0x28); 21840b57cec5SDimitry Andric } 21850b57cec5SDimitry Andric 21860b57cec5SDimitry Andric // Get the thread's register context. 21870b57cec5SDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 21880b57cec5SDimitry Andric const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); 21890b57cec5SDimitry Andric if (!reg_info) { 21909dba64beSDimitry Andric LLDB_LOGF(log, 21919dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, requested " 21920b57cec5SDimitry Andric "register %" PRIu32 " returned NULL", 21930b57cec5SDimitry Andric __FUNCTION__, reg_index); 21940b57cec5SDimitry Andric return SendErrorResponse(0x48); 21950b57cec5SDimitry Andric } 21960b57cec5SDimitry Andric 21970b57cec5SDimitry Andric // Return the end of registers response if we've iterated one past the end of 21980b57cec5SDimitry Andric // the register set. 21990b57cec5SDimitry Andric if (reg_index >= reg_context.GetUserRegisterCount()) { 22009dba64beSDimitry Andric LLDB_LOGF(log, 22019dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, requested " 22020b57cec5SDimitry Andric "register %" PRIu32 " beyond register count %" PRIu32, 22030b57cec5SDimitry Andric __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); 22040b57cec5SDimitry Andric return SendErrorResponse(0x47); 22050b57cec5SDimitry Andric } 22060b57cec5SDimitry Andric 2207349cc55cSDimitry Andric if (reg_size != reg_info->byte_size) 22080b57cec5SDimitry Andric return SendIllFormedResponse(packet, "P packet register size is incorrect"); 22090b57cec5SDimitry Andric 22100b57cec5SDimitry Andric // Build the reginfos response. 22110b57cec5SDimitry Andric StreamGDBRemote response; 22120b57cec5SDimitry Andric 2213fe6060f1SDimitry Andric RegisterValue reg_value(makeArrayRef(reg_bytes, reg_size), 2214fe6060f1SDimitry Andric m_current_process->GetArchitecture().GetByteOrder()); 22150b57cec5SDimitry Andric Status error = reg_context.WriteRegister(reg_info, reg_value); 22160b57cec5SDimitry Andric if (error.Fail()) { 22179dba64beSDimitry Andric LLDB_LOGF(log, 22189dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, write of " 22190b57cec5SDimitry Andric "requested register %" PRIu32 " (%s) failed: %s", 22200b57cec5SDimitry Andric __FUNCTION__, reg_index, reg_info->name, error.AsCString()); 22210b57cec5SDimitry Andric return SendErrorResponse(0x32); 22220b57cec5SDimitry Andric } 22230b57cec5SDimitry Andric 22240b57cec5SDimitry Andric return SendOKResponse(); 22250b57cec5SDimitry Andric } 22260b57cec5SDimitry Andric 22270b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 22280b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { 222981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 22300b57cec5SDimitry Andric 22310b57cec5SDimitry Andric // Parse out which variant of $H is requested. 22320b57cec5SDimitry Andric packet.SetFilePos(strlen("H")); 22330b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) { 22349dba64beSDimitry Andric LLDB_LOGF(log, 22359dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, H command " 22360b57cec5SDimitry Andric "missing {g,c} variant", 22370b57cec5SDimitry Andric __FUNCTION__); 22380b57cec5SDimitry Andric return SendIllFormedResponse(packet, "H command missing {g,c} variant"); 22390b57cec5SDimitry Andric } 22400b57cec5SDimitry Andric 22410b57cec5SDimitry Andric const char h_variant = packet.GetChar(); 2242fe6060f1SDimitry Andric NativeProcessProtocol *default_process; 22430b57cec5SDimitry Andric switch (h_variant) { 22440b57cec5SDimitry Andric case 'g': 2245fe6060f1SDimitry Andric default_process = m_current_process; 22460b57cec5SDimitry Andric break; 22470b57cec5SDimitry Andric 22480b57cec5SDimitry Andric case 'c': 2249fe6060f1SDimitry Andric default_process = m_continue_process; 22500b57cec5SDimitry Andric break; 22510b57cec5SDimitry Andric 22520b57cec5SDimitry Andric default: 22539dba64beSDimitry Andric LLDB_LOGF( 22549dba64beSDimitry Andric log, 22550b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", 22560b57cec5SDimitry Andric __FUNCTION__, h_variant); 22570b57cec5SDimitry Andric return SendIllFormedResponse(packet, 22580b57cec5SDimitry Andric "H variant unsupported, should be c or g"); 22590b57cec5SDimitry Andric } 22600b57cec5SDimitry Andric 22610b57cec5SDimitry Andric // Parse out the thread number. 2262fe6060f1SDimitry Andric auto pid_tid = packet.GetPidTid(default_process ? default_process->GetID() 2263fe6060f1SDimitry Andric : LLDB_INVALID_PROCESS_ID); 2264fe6060f1SDimitry Andric if (!pid_tid) 2265fe6060f1SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 2266fe6060f1SDimitry Andric inconvertibleErrorCode(), "Malformed thread-id")); 2267fe6060f1SDimitry Andric 2268fe6060f1SDimitry Andric lldb::pid_t pid = pid_tid->first; 2269fe6060f1SDimitry Andric lldb::tid_t tid = pid_tid->second; 2270fe6060f1SDimitry Andric 2271fe6060f1SDimitry Andric if (pid == StringExtractorGDBRemote::AllProcesses) 2272fe6060f1SDimitry Andric return SendUnimplementedResponse("Selecting all processes not supported"); 2273fe6060f1SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 2274fe6060f1SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 2275fe6060f1SDimitry Andric inconvertibleErrorCode(), "No current process and no PID provided")); 2276fe6060f1SDimitry Andric 2277fe6060f1SDimitry Andric // Check the process ID and find respective process instance. 2278fe6060f1SDimitry Andric auto new_process_it = m_debugged_processes.find(pid); 2279fe6060f1SDimitry Andric if (new_process_it == m_debugged_processes.end()) 2280fe6060f1SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 2281fe6060f1SDimitry Andric inconvertibleErrorCode(), 2282fe6060f1SDimitry Andric llvm::formatv("No process with PID {0} debugged", pid))); 22830b57cec5SDimitry Andric 22840b57cec5SDimitry Andric // Ensure we have the given thread when not specifying -1 (all threads) or 0 22850b57cec5SDimitry Andric // (any thread). 22860b57cec5SDimitry Andric if (tid != LLDB_INVALID_THREAD_ID && tid != 0) { 2287fe6060f1SDimitry Andric NativeThreadProtocol *thread = new_process_it->second->GetThreadByID(tid); 22880b57cec5SDimitry Andric if (!thread) { 22899dba64beSDimitry Andric LLDB_LOGF(log, 22909dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 22910b57cec5SDimitry Andric " not found", 22920b57cec5SDimitry Andric __FUNCTION__, tid); 22930b57cec5SDimitry Andric return SendErrorResponse(0x15); 22940b57cec5SDimitry Andric } 22950b57cec5SDimitry Andric } 22960b57cec5SDimitry Andric 2297fe6060f1SDimitry Andric // Now switch the given process and thread type. 22980b57cec5SDimitry Andric switch (h_variant) { 22990b57cec5SDimitry Andric case 'g': 2300fe6060f1SDimitry Andric m_current_process = new_process_it->second.get(); 23010b57cec5SDimitry Andric SetCurrentThreadID(tid); 23020b57cec5SDimitry Andric break; 23030b57cec5SDimitry Andric 23040b57cec5SDimitry Andric case 'c': 2305fe6060f1SDimitry Andric m_continue_process = new_process_it->second.get(); 23060b57cec5SDimitry Andric SetContinueThreadID(tid); 23070b57cec5SDimitry Andric break; 23080b57cec5SDimitry Andric 23090b57cec5SDimitry Andric default: 23100b57cec5SDimitry Andric assert(false && "unsupported $H variant - shouldn't get here"); 23110b57cec5SDimitry Andric return SendIllFormedResponse(packet, 23120b57cec5SDimitry Andric "H variant unsupported, should be c or g"); 23130b57cec5SDimitry Andric } 23140b57cec5SDimitry Andric 23150b57cec5SDimitry Andric return SendOKResponse(); 23160b57cec5SDimitry Andric } 23170b57cec5SDimitry Andric 23180b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 23190b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) { 232081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 23210b57cec5SDimitry Andric 23220b57cec5SDimitry Andric // Fail if we don't have a current process. 2323fe6060f1SDimitry Andric if (!m_current_process || 2324fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 23259dba64beSDimitry Andric LLDB_LOGF( 23269dba64beSDimitry Andric log, 23270b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 23280b57cec5SDimitry Andric __FUNCTION__); 23290b57cec5SDimitry Andric return SendErrorResponse(0x15); 23300b57cec5SDimitry Andric } 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andric packet.SetFilePos(::strlen("I")); 23330b57cec5SDimitry Andric uint8_t tmp[4096]; 23340b57cec5SDimitry Andric for (;;) { 23350b57cec5SDimitry Andric size_t read = packet.GetHexBytesAvail(tmp); 23360b57cec5SDimitry Andric if (read == 0) { 23370b57cec5SDimitry Andric break; 23380b57cec5SDimitry Andric } 23390b57cec5SDimitry Andric // write directly to stdin *this might block if stdin buffer is full* 23400b57cec5SDimitry Andric // TODO: enqueue this block in circular buffer and send window size to 23410b57cec5SDimitry Andric // remote host 23420b57cec5SDimitry Andric ConnectionStatus status; 23430b57cec5SDimitry Andric Status error; 23440b57cec5SDimitry Andric m_stdio_communication.Write(tmp, read, status, &error); 23450b57cec5SDimitry Andric if (error.Fail()) { 23460b57cec5SDimitry Andric return SendErrorResponse(0x15); 23470b57cec5SDimitry Andric } 23480b57cec5SDimitry Andric } 23490b57cec5SDimitry Andric 23500b57cec5SDimitry Andric return SendOKResponse(); 23510b57cec5SDimitry Andric } 23520b57cec5SDimitry Andric 23530b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 23540b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_interrupt( 23550b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 235681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 23570b57cec5SDimitry Andric 23580b57cec5SDimitry Andric // Fail if we don't have a current process. 2359fe6060f1SDimitry Andric if (!m_current_process || 2360fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 23610b57cec5SDimitry Andric LLDB_LOG(log, "failed, no process available"); 23620b57cec5SDimitry Andric return SendErrorResponse(0x15); 23630b57cec5SDimitry Andric } 23640b57cec5SDimitry Andric 23650b57cec5SDimitry Andric // Interrupt the process. 2366fe6060f1SDimitry Andric Status error = m_current_process->Interrupt(); 23670b57cec5SDimitry Andric if (error.Fail()) { 2368fe6060f1SDimitry Andric LLDB_LOG(log, "failed for process {0}: {1}", m_current_process->GetID(), 23690b57cec5SDimitry Andric error); 23700b57cec5SDimitry Andric return SendErrorResponse(GDBRemoteServerError::eErrorResume); 23710b57cec5SDimitry Andric } 23720b57cec5SDimitry Andric 2373fe6060f1SDimitry Andric LLDB_LOG(log, "stopped process {0}", m_current_process->GetID()); 23740b57cec5SDimitry Andric 23750b57cec5SDimitry Andric // No response required from stop all. 23760b57cec5SDimitry Andric return PacketResult::Success; 23770b57cec5SDimitry Andric } 23780b57cec5SDimitry Andric 23790b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 23800b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_memory_read( 23810b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 238281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 23830b57cec5SDimitry Andric 2384fe6060f1SDimitry Andric if (!m_current_process || 2385fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 23869dba64beSDimitry Andric LLDB_LOGF( 23879dba64beSDimitry Andric log, 23880b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 23890b57cec5SDimitry Andric __FUNCTION__); 23900b57cec5SDimitry Andric return SendErrorResponse(0x15); 23910b57cec5SDimitry Andric } 23920b57cec5SDimitry Andric 23930b57cec5SDimitry Andric // Parse out the memory address. 23940b57cec5SDimitry Andric packet.SetFilePos(strlen("m")); 23950b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 23960b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short m packet"); 23970b57cec5SDimitry Andric 23980b57cec5SDimitry Andric // Read the address. Punting on validation. 23990b57cec5SDimitry Andric // FIXME replace with Hex U64 read with no default value that fails on failed 24000b57cec5SDimitry Andric // read. 24010b57cec5SDimitry Andric const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0); 24020b57cec5SDimitry Andric 24030b57cec5SDimitry Andric // Validate comma. 24040b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) 24050b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Comma sep missing in m packet"); 24060b57cec5SDimitry Andric 24070b57cec5SDimitry Andric // Get # bytes to read. 24080b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 24090b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Length missing in m packet"); 24100b57cec5SDimitry Andric 24110b57cec5SDimitry Andric const uint64_t byte_count = packet.GetHexMaxU64(false, 0); 24120b57cec5SDimitry Andric if (byte_count == 0) { 24139dba64beSDimitry Andric LLDB_LOGF(log, 24149dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s nothing to read: " 24150b57cec5SDimitry Andric "zero-length packet", 24160b57cec5SDimitry Andric __FUNCTION__); 24170b57cec5SDimitry Andric return SendOKResponse(); 24180b57cec5SDimitry Andric } 24190b57cec5SDimitry Andric 24200b57cec5SDimitry Andric // Allocate the response buffer. 24210b57cec5SDimitry Andric std::string buf(byte_count, '\0'); 24220b57cec5SDimitry Andric if (buf.empty()) 24230b57cec5SDimitry Andric return SendErrorResponse(0x78); 24240b57cec5SDimitry Andric 24250b57cec5SDimitry Andric // Retrieve the process memory. 24260b57cec5SDimitry Andric size_t bytes_read = 0; 2427fe6060f1SDimitry Andric Status error = m_current_process->ReadMemoryWithoutTrap( 24280b57cec5SDimitry Andric read_addr, &buf[0], byte_count, bytes_read); 24290b57cec5SDimitry Andric if (error.Fail()) { 24309dba64beSDimitry Andric LLDB_LOGF(log, 24319dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 24320b57cec5SDimitry Andric " mem 0x%" PRIx64 ": failed to read. Error: %s", 2433fe6060f1SDimitry Andric __FUNCTION__, m_current_process->GetID(), read_addr, 24340b57cec5SDimitry Andric error.AsCString()); 24350b57cec5SDimitry Andric return SendErrorResponse(0x08); 24360b57cec5SDimitry Andric } 24370b57cec5SDimitry Andric 24380b57cec5SDimitry Andric if (bytes_read == 0) { 24399dba64beSDimitry Andric LLDB_LOGF(log, 24409dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 24410b57cec5SDimitry Andric " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", 2442fe6060f1SDimitry Andric __FUNCTION__, m_current_process->GetID(), read_addr, byte_count); 24430b57cec5SDimitry Andric return SendErrorResponse(0x08); 24440b57cec5SDimitry Andric } 24450b57cec5SDimitry Andric 24460b57cec5SDimitry Andric StreamGDBRemote response; 24470b57cec5SDimitry Andric packet.SetFilePos(0); 24480b57cec5SDimitry Andric char kind = packet.GetChar('?'); 24490b57cec5SDimitry Andric if (kind == 'x') 24500b57cec5SDimitry Andric response.PutEscapedBytes(buf.data(), byte_count); 24510b57cec5SDimitry Andric else { 24520b57cec5SDimitry Andric assert(kind == 'm'); 24530b57cec5SDimitry Andric for (size_t i = 0; i < bytes_read; ++i) 24540b57cec5SDimitry Andric response.PutHex8(buf[i]); 24550b57cec5SDimitry Andric } 24560b57cec5SDimitry Andric 24570b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 24580b57cec5SDimitry Andric } 24590b57cec5SDimitry Andric 24600b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 2461e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) { 246281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 2463e8d8bef9SDimitry Andric 2464fe6060f1SDimitry Andric if (!m_current_process || 2465fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 2466e8d8bef9SDimitry Andric LLDB_LOGF( 2467e8d8bef9SDimitry Andric log, 2468e8d8bef9SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 2469e8d8bef9SDimitry Andric __FUNCTION__); 2470e8d8bef9SDimitry Andric return SendErrorResponse(0x15); 2471e8d8bef9SDimitry Andric } 2472e8d8bef9SDimitry Andric 2473e8d8bef9SDimitry Andric // Parse out the memory address. 2474e8d8bef9SDimitry Andric packet.SetFilePos(strlen("_M")); 2475e8d8bef9SDimitry Andric if (packet.GetBytesLeft() < 1) 2476e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Too short _M packet"); 2477e8d8bef9SDimitry Andric 2478e8d8bef9SDimitry Andric const lldb::addr_t size = packet.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); 2479e8d8bef9SDimitry Andric if (size == LLDB_INVALID_ADDRESS) 2480e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Address not valid"); 2481e8d8bef9SDimitry Andric if (packet.GetChar() != ',') 2482e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Bad packet"); 2483e8d8bef9SDimitry Andric Permissions perms = {}; 2484e8d8bef9SDimitry Andric while (packet.GetBytesLeft() > 0) { 2485e8d8bef9SDimitry Andric switch (packet.GetChar()) { 2486e8d8bef9SDimitry Andric case 'r': 2487e8d8bef9SDimitry Andric perms |= ePermissionsReadable; 2488e8d8bef9SDimitry Andric break; 2489e8d8bef9SDimitry Andric case 'w': 2490e8d8bef9SDimitry Andric perms |= ePermissionsWritable; 2491e8d8bef9SDimitry Andric break; 2492e8d8bef9SDimitry Andric case 'x': 2493e8d8bef9SDimitry Andric perms |= ePermissionsExecutable; 2494e8d8bef9SDimitry Andric break; 2495e8d8bef9SDimitry Andric default: 2496e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Bad permissions"); 2497e8d8bef9SDimitry Andric } 2498e8d8bef9SDimitry Andric } 2499e8d8bef9SDimitry Andric 2500fe6060f1SDimitry Andric llvm::Expected<addr_t> addr = m_current_process->AllocateMemory(size, perms); 2501e8d8bef9SDimitry Andric if (!addr) 2502e8d8bef9SDimitry Andric return SendErrorResponse(addr.takeError()); 2503e8d8bef9SDimitry Andric 2504e8d8bef9SDimitry Andric StreamGDBRemote response; 2505e8d8bef9SDimitry Andric response.PutHex64(*addr); 2506e8d8bef9SDimitry Andric return SendPacketNoLock(response.GetString()); 2507e8d8bef9SDimitry Andric } 2508e8d8bef9SDimitry Andric 2509e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 2510e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) { 251181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 2512e8d8bef9SDimitry Andric 2513fe6060f1SDimitry Andric if (!m_current_process || 2514fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 2515e8d8bef9SDimitry Andric LLDB_LOGF( 2516e8d8bef9SDimitry Andric log, 2517e8d8bef9SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 2518e8d8bef9SDimitry Andric __FUNCTION__); 2519e8d8bef9SDimitry Andric return SendErrorResponse(0x15); 2520e8d8bef9SDimitry Andric } 2521e8d8bef9SDimitry Andric 2522e8d8bef9SDimitry Andric // Parse out the memory address. 2523e8d8bef9SDimitry Andric packet.SetFilePos(strlen("_m")); 2524e8d8bef9SDimitry Andric if (packet.GetBytesLeft() < 1) 2525e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Too short m packet"); 2526e8d8bef9SDimitry Andric 2527e8d8bef9SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); 2528e8d8bef9SDimitry Andric if (addr == LLDB_INVALID_ADDRESS) 2529e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "Address not valid"); 2530e8d8bef9SDimitry Andric 2531fe6060f1SDimitry Andric if (llvm::Error Err = m_current_process->DeallocateMemory(addr)) 2532e8d8bef9SDimitry Andric return SendErrorResponse(std::move(Err)); 2533e8d8bef9SDimitry Andric 2534e8d8bef9SDimitry Andric return SendOKResponse(); 2535e8d8bef9SDimitry Andric } 2536e8d8bef9SDimitry Andric 2537e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 25380b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) { 253981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 25400b57cec5SDimitry Andric 2541fe6060f1SDimitry Andric if (!m_current_process || 2542fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 25439dba64beSDimitry Andric LLDB_LOGF( 25449dba64beSDimitry Andric log, 25450b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 25460b57cec5SDimitry Andric __FUNCTION__); 25470b57cec5SDimitry Andric return SendErrorResponse(0x15); 25480b57cec5SDimitry Andric } 25490b57cec5SDimitry Andric 25500b57cec5SDimitry Andric // Parse out the memory address. 25510b57cec5SDimitry Andric packet.SetFilePos(strlen("M")); 25520b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 25530b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short M packet"); 25540b57cec5SDimitry Andric 25550b57cec5SDimitry Andric // Read the address. Punting on validation. 25560b57cec5SDimitry Andric // FIXME replace with Hex U64 read with no default value that fails on failed 25570b57cec5SDimitry Andric // read. 25580b57cec5SDimitry Andric const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0); 25590b57cec5SDimitry Andric 25600b57cec5SDimitry Andric // Validate comma. 25610b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ',')) 25620b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Comma sep missing in M packet"); 25630b57cec5SDimitry Andric 25640b57cec5SDimitry Andric // Get # bytes to read. 25650b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 25660b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Length missing in M packet"); 25670b57cec5SDimitry Andric 25680b57cec5SDimitry Andric const uint64_t byte_count = packet.GetHexMaxU64(false, 0); 25690b57cec5SDimitry Andric if (byte_count == 0) { 25700b57cec5SDimitry Andric LLDB_LOG(log, "nothing to write: zero-length packet"); 25710b57cec5SDimitry Andric return PacketResult::Success; 25720b57cec5SDimitry Andric } 25730b57cec5SDimitry Andric 25740b57cec5SDimitry Andric // Validate colon. 25750b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':')) 25760b57cec5SDimitry Andric return SendIllFormedResponse( 25770b57cec5SDimitry Andric packet, "Comma sep missing in M packet after byte length"); 25780b57cec5SDimitry Andric 25790b57cec5SDimitry Andric // Allocate the conversion buffer. 25800b57cec5SDimitry Andric std::vector<uint8_t> buf(byte_count, 0); 25810b57cec5SDimitry Andric if (buf.empty()) 25820b57cec5SDimitry Andric return SendErrorResponse(0x78); 25830b57cec5SDimitry Andric 25840b57cec5SDimitry Andric // Convert the hex memory write contents to bytes. 25850b57cec5SDimitry Andric StreamGDBRemote response; 25860b57cec5SDimitry Andric const uint64_t convert_count = packet.GetHexBytes(buf, 0); 25870b57cec5SDimitry Andric if (convert_count != byte_count) { 25880b57cec5SDimitry Andric LLDB_LOG(log, 25890b57cec5SDimitry Andric "pid {0} mem {1:x}: asked to write {2} bytes, but only found {3} " 25900b57cec5SDimitry Andric "to convert.", 2591fe6060f1SDimitry Andric m_current_process->GetID(), write_addr, byte_count, convert_count); 25920b57cec5SDimitry Andric return SendIllFormedResponse(packet, "M content byte length specified did " 25930b57cec5SDimitry Andric "not match hex-encoded content " 25940b57cec5SDimitry Andric "length"); 25950b57cec5SDimitry Andric } 25960b57cec5SDimitry Andric 25970b57cec5SDimitry Andric // Write the process memory. 25980b57cec5SDimitry Andric size_t bytes_written = 0; 2599fe6060f1SDimitry Andric Status error = m_current_process->WriteMemory(write_addr, &buf[0], byte_count, 2600fe6060f1SDimitry Andric bytes_written); 26010b57cec5SDimitry Andric if (error.Fail()) { 26020b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} mem {1:x}: failed to write. Error: {2}", 2603fe6060f1SDimitry Andric m_current_process->GetID(), write_addr, error); 26040b57cec5SDimitry Andric return SendErrorResponse(0x09); 26050b57cec5SDimitry Andric } 26060b57cec5SDimitry Andric 26070b57cec5SDimitry Andric if (bytes_written == 0) { 26080b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} mem {1:x}: wrote 0 of {2} requested bytes", 2609fe6060f1SDimitry Andric m_current_process->GetID(), write_addr, byte_count); 26100b57cec5SDimitry Andric return SendErrorResponse(0x09); 26110b57cec5SDimitry Andric } 26120b57cec5SDimitry Andric 26130b57cec5SDimitry Andric return SendOKResponse(); 26140b57cec5SDimitry Andric } 26150b57cec5SDimitry Andric 26160b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 26170b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( 26180b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 261981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 26200b57cec5SDimitry Andric 26210b57cec5SDimitry Andric // Currently only the NativeProcessProtocol knows if it can handle a 26220b57cec5SDimitry Andric // qMemoryRegionInfoSupported request, but we're not guaranteed to be 26230b57cec5SDimitry Andric // attached to a process. For now we'll assume the client only asks this 26240b57cec5SDimitry Andric // when a process is being debugged. 26250b57cec5SDimitry Andric 26260b57cec5SDimitry Andric // Ensure we have a process running; otherwise, we can't figure this out 26270b57cec5SDimitry Andric // since we won't have a NativeProcessProtocol. 2628fe6060f1SDimitry Andric if (!m_current_process || 2629fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 26309dba64beSDimitry Andric LLDB_LOGF( 26319dba64beSDimitry Andric log, 26320b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 26330b57cec5SDimitry Andric __FUNCTION__); 26340b57cec5SDimitry Andric return SendErrorResponse(0x15); 26350b57cec5SDimitry Andric } 26360b57cec5SDimitry Andric 26370b57cec5SDimitry Andric // Test if we can get any region back when asking for the region around NULL. 26380b57cec5SDimitry Andric MemoryRegionInfo region_info; 2639fe6060f1SDimitry Andric const Status error = m_current_process->GetMemoryRegionInfo(0, region_info); 26400b57cec5SDimitry Andric if (error.Fail()) { 26410b57cec5SDimitry Andric // We don't support memory region info collection for this 26420b57cec5SDimitry Andric // NativeProcessProtocol. 26430b57cec5SDimitry Andric return SendUnimplementedResponse(""); 26440b57cec5SDimitry Andric } 26450b57cec5SDimitry Andric 26460b57cec5SDimitry Andric return SendOKResponse(); 26470b57cec5SDimitry Andric } 26480b57cec5SDimitry Andric 26490b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 26500b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo( 26510b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 265281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 26530b57cec5SDimitry Andric 26540b57cec5SDimitry Andric // Ensure we have a process. 2655fe6060f1SDimitry Andric if (!m_current_process || 2656fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 26579dba64beSDimitry Andric LLDB_LOGF( 26589dba64beSDimitry Andric log, 26590b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 26600b57cec5SDimitry Andric __FUNCTION__); 26610b57cec5SDimitry Andric return SendErrorResponse(0x15); 26620b57cec5SDimitry Andric } 26630b57cec5SDimitry Andric 26640b57cec5SDimitry Andric // Parse out the memory address. 26650b57cec5SDimitry Andric packet.SetFilePos(strlen("qMemoryRegionInfo:")); 26660b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 26670b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet"); 26680b57cec5SDimitry Andric 26690b57cec5SDimitry Andric // Read the address. Punting on validation. 26700b57cec5SDimitry Andric const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0); 26710b57cec5SDimitry Andric 26720b57cec5SDimitry Andric StreamGDBRemote response; 26730b57cec5SDimitry Andric 26740b57cec5SDimitry Andric // Get the memory region info for the target address. 26750b57cec5SDimitry Andric MemoryRegionInfo region_info; 26760b57cec5SDimitry Andric const Status error = 2677fe6060f1SDimitry Andric m_current_process->GetMemoryRegionInfo(read_addr, region_info); 26780b57cec5SDimitry Andric if (error.Fail()) { 26790b57cec5SDimitry Andric // Return the error message. 26800b57cec5SDimitry Andric 26810b57cec5SDimitry Andric response.PutCString("error:"); 26820b57cec5SDimitry Andric response.PutStringAsRawHex8(error.AsCString()); 26830b57cec5SDimitry Andric response.PutChar(';'); 26840b57cec5SDimitry Andric } else { 26850b57cec5SDimitry Andric // Range start and size. 26860b57cec5SDimitry Andric response.Printf("start:%" PRIx64 ";size:%" PRIx64 ";", 26870b57cec5SDimitry Andric region_info.GetRange().GetRangeBase(), 26880b57cec5SDimitry Andric region_info.GetRange().GetByteSize()); 26890b57cec5SDimitry Andric 26900b57cec5SDimitry Andric // Permissions. 26910b57cec5SDimitry Andric if (region_info.GetReadable() || region_info.GetWritable() || 26920b57cec5SDimitry Andric region_info.GetExecutable()) { 26930b57cec5SDimitry Andric // Write permissions info. 26940b57cec5SDimitry Andric response.PutCString("permissions:"); 26950b57cec5SDimitry Andric 26960b57cec5SDimitry Andric if (region_info.GetReadable()) 26970b57cec5SDimitry Andric response.PutChar('r'); 26980b57cec5SDimitry Andric if (region_info.GetWritable()) 26990b57cec5SDimitry Andric response.PutChar('w'); 27000b57cec5SDimitry Andric if (region_info.GetExecutable()) 27010b57cec5SDimitry Andric response.PutChar('x'); 27020b57cec5SDimitry Andric 27030b57cec5SDimitry Andric response.PutChar(';'); 27040b57cec5SDimitry Andric } 27050b57cec5SDimitry Andric 2706e8d8bef9SDimitry Andric // Flags 2707e8d8bef9SDimitry Andric MemoryRegionInfo::OptionalBool memory_tagged = 2708e8d8bef9SDimitry Andric region_info.GetMemoryTagged(); 2709e8d8bef9SDimitry Andric if (memory_tagged != MemoryRegionInfo::eDontKnow) { 2710e8d8bef9SDimitry Andric response.PutCString("flags:"); 2711e8d8bef9SDimitry Andric if (memory_tagged == MemoryRegionInfo::eYes) { 2712e8d8bef9SDimitry Andric response.PutCString("mt"); 2713e8d8bef9SDimitry Andric } 2714e8d8bef9SDimitry Andric response.PutChar(';'); 2715e8d8bef9SDimitry Andric } 2716e8d8bef9SDimitry Andric 27170b57cec5SDimitry Andric // Name 27180b57cec5SDimitry Andric ConstString name = region_info.GetName(); 27190b57cec5SDimitry Andric if (name) { 27200b57cec5SDimitry Andric response.PutCString("name:"); 27215ffd83dbSDimitry Andric response.PutStringAsRawHex8(name.GetStringRef()); 27220b57cec5SDimitry Andric response.PutChar(';'); 27230b57cec5SDimitry Andric } 27240b57cec5SDimitry Andric } 27250b57cec5SDimitry Andric 27260b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 27270b57cec5SDimitry Andric } 27280b57cec5SDimitry Andric 27290b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 27300b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) { 27310b57cec5SDimitry Andric // Ensure we have a process. 2732fe6060f1SDimitry Andric if (!m_current_process || 2733fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 273481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 27350b57cec5SDimitry Andric LLDB_LOG(log, "failed, no process available"); 27360b57cec5SDimitry Andric return SendErrorResponse(0x15); 27370b57cec5SDimitry Andric } 27380b57cec5SDimitry Andric 27390b57cec5SDimitry Andric // Parse out software or hardware breakpoint or watchpoint requested. 27400b57cec5SDimitry Andric packet.SetFilePos(strlen("Z")); 27410b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 27420b57cec5SDimitry Andric return SendIllFormedResponse( 27430b57cec5SDimitry Andric packet, "Too short Z packet, missing software/hardware specifier"); 27440b57cec5SDimitry Andric 27450b57cec5SDimitry Andric bool want_breakpoint = true; 27460b57cec5SDimitry Andric bool want_hardware = false; 27470b57cec5SDimitry Andric uint32_t watch_flags = 0; 27480b57cec5SDimitry Andric 27490b57cec5SDimitry Andric const GDBStoppointType stoppoint_type = 27500b57cec5SDimitry Andric GDBStoppointType(packet.GetS32(eStoppointInvalid)); 27510b57cec5SDimitry Andric switch (stoppoint_type) { 27520b57cec5SDimitry Andric case eBreakpointSoftware: 27530b57cec5SDimitry Andric want_hardware = false; 27540b57cec5SDimitry Andric want_breakpoint = true; 27550b57cec5SDimitry Andric break; 27560b57cec5SDimitry Andric case eBreakpointHardware: 27570b57cec5SDimitry Andric want_hardware = true; 27580b57cec5SDimitry Andric want_breakpoint = true; 27590b57cec5SDimitry Andric break; 27600b57cec5SDimitry Andric case eWatchpointWrite: 27610b57cec5SDimitry Andric watch_flags = 1; 27620b57cec5SDimitry Andric want_hardware = true; 27630b57cec5SDimitry Andric want_breakpoint = false; 27640b57cec5SDimitry Andric break; 27650b57cec5SDimitry Andric case eWatchpointRead: 27660b57cec5SDimitry Andric watch_flags = 2; 27670b57cec5SDimitry Andric want_hardware = true; 27680b57cec5SDimitry Andric want_breakpoint = false; 27690b57cec5SDimitry Andric break; 27700b57cec5SDimitry Andric case eWatchpointReadWrite: 27710b57cec5SDimitry Andric watch_flags = 3; 27720b57cec5SDimitry Andric want_hardware = true; 27730b57cec5SDimitry Andric want_breakpoint = false; 27740b57cec5SDimitry Andric break; 27750b57cec5SDimitry Andric case eStoppointInvalid: 27760b57cec5SDimitry Andric return SendIllFormedResponse( 27770b57cec5SDimitry Andric packet, "Z packet had invalid software/hardware specifier"); 27780b57cec5SDimitry Andric } 27790b57cec5SDimitry Andric 27800b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') 27810b57cec5SDimitry Andric return SendIllFormedResponse( 27820b57cec5SDimitry Andric packet, "Malformed Z packet, expecting comma after stoppoint type"); 27830b57cec5SDimitry Andric 27840b57cec5SDimitry Andric // Parse out the stoppoint address. 27850b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 27860b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short Z packet, missing address"); 27870b57cec5SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(false, 0); 27880b57cec5SDimitry Andric 27890b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') 27900b57cec5SDimitry Andric return SendIllFormedResponse( 27910b57cec5SDimitry Andric packet, "Malformed Z packet, expecting comma after address"); 27920b57cec5SDimitry Andric 27930b57cec5SDimitry Andric // Parse out the stoppoint size (i.e. size hint for opcode size). 27940b57cec5SDimitry Andric const uint32_t size = 27950b57cec5SDimitry Andric packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max()); 27960b57cec5SDimitry Andric if (size == std::numeric_limits<uint32_t>::max()) 27970b57cec5SDimitry Andric return SendIllFormedResponse( 27980b57cec5SDimitry Andric packet, "Malformed Z packet, failed to parse size argument"); 27990b57cec5SDimitry Andric 28000b57cec5SDimitry Andric if (want_breakpoint) { 28010b57cec5SDimitry Andric // Try to set the breakpoint. 28020b57cec5SDimitry Andric const Status error = 2803fe6060f1SDimitry Andric m_current_process->SetBreakpoint(addr, size, want_hardware); 28040b57cec5SDimitry Andric if (error.Success()) 28050b57cec5SDimitry Andric return SendOKResponse(); 280681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Breakpoints); 28070b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to set breakpoint: {1}", 2808fe6060f1SDimitry Andric m_current_process->GetID(), error); 28090b57cec5SDimitry Andric return SendErrorResponse(0x09); 28100b57cec5SDimitry Andric } else { 28110b57cec5SDimitry Andric // Try to set the watchpoint. 2812fe6060f1SDimitry Andric const Status error = m_current_process->SetWatchpoint( 28130b57cec5SDimitry Andric addr, size, watch_flags, want_hardware); 28140b57cec5SDimitry Andric if (error.Success()) 28150b57cec5SDimitry Andric return SendOKResponse(); 281681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Watchpoints); 28170b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to set watchpoint: {1}", 2818fe6060f1SDimitry Andric m_current_process->GetID(), error); 28190b57cec5SDimitry Andric return SendErrorResponse(0x09); 28200b57cec5SDimitry Andric } 28210b57cec5SDimitry Andric } 28220b57cec5SDimitry Andric 28230b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 28240b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) { 28250b57cec5SDimitry Andric // Ensure we have a process. 2826fe6060f1SDimitry Andric if (!m_current_process || 2827fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 282881ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 28290b57cec5SDimitry Andric LLDB_LOG(log, "failed, no process available"); 28300b57cec5SDimitry Andric return SendErrorResponse(0x15); 28310b57cec5SDimitry Andric } 28320b57cec5SDimitry Andric 28330b57cec5SDimitry Andric // Parse out software or hardware breakpoint or watchpoint requested. 28340b57cec5SDimitry Andric packet.SetFilePos(strlen("z")); 28350b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 28360b57cec5SDimitry Andric return SendIllFormedResponse( 28370b57cec5SDimitry Andric packet, "Too short z packet, missing software/hardware specifier"); 28380b57cec5SDimitry Andric 28390b57cec5SDimitry Andric bool want_breakpoint = true; 28400b57cec5SDimitry Andric bool want_hardware = false; 28410b57cec5SDimitry Andric 28420b57cec5SDimitry Andric const GDBStoppointType stoppoint_type = 28430b57cec5SDimitry Andric GDBStoppointType(packet.GetS32(eStoppointInvalid)); 28440b57cec5SDimitry Andric switch (stoppoint_type) { 28450b57cec5SDimitry Andric case eBreakpointHardware: 28460b57cec5SDimitry Andric want_breakpoint = true; 28470b57cec5SDimitry Andric want_hardware = true; 28480b57cec5SDimitry Andric break; 28490b57cec5SDimitry Andric case eBreakpointSoftware: 28500b57cec5SDimitry Andric want_breakpoint = true; 28510b57cec5SDimitry Andric break; 28520b57cec5SDimitry Andric case eWatchpointWrite: 28530b57cec5SDimitry Andric want_breakpoint = false; 28540b57cec5SDimitry Andric break; 28550b57cec5SDimitry Andric case eWatchpointRead: 28560b57cec5SDimitry Andric want_breakpoint = false; 28570b57cec5SDimitry Andric break; 28580b57cec5SDimitry Andric case eWatchpointReadWrite: 28590b57cec5SDimitry Andric want_breakpoint = false; 28600b57cec5SDimitry Andric break; 28610b57cec5SDimitry Andric default: 28620b57cec5SDimitry Andric return SendIllFormedResponse( 28630b57cec5SDimitry Andric packet, "z packet had invalid software/hardware specifier"); 28640b57cec5SDimitry Andric } 28650b57cec5SDimitry Andric 28660b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') 28670b57cec5SDimitry Andric return SendIllFormedResponse( 28680b57cec5SDimitry Andric packet, "Malformed z packet, expecting comma after stoppoint type"); 28690b57cec5SDimitry Andric 28700b57cec5SDimitry Andric // Parse out the stoppoint address. 28710b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 28720b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Too short z packet, missing address"); 28730b57cec5SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(false, 0); 28740b57cec5SDimitry Andric 28750b57cec5SDimitry Andric if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',') 28760b57cec5SDimitry Andric return SendIllFormedResponse( 28770b57cec5SDimitry Andric packet, "Malformed z packet, expecting comma after address"); 28780b57cec5SDimitry Andric 28790b57cec5SDimitry Andric /* 28800b57cec5SDimitry Andric // Parse out the stoppoint size (i.e. size hint for opcode size). 28810b57cec5SDimitry Andric const uint32_t size = packet.GetHexMaxU32 (false, 28820b57cec5SDimitry Andric std::numeric_limits<uint32_t>::max ()); 28830b57cec5SDimitry Andric if (size == std::numeric_limits<uint32_t>::max ()) 28840b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Malformed z packet, failed to parse 28850b57cec5SDimitry Andric size argument"); 28860b57cec5SDimitry Andric */ 28870b57cec5SDimitry Andric 28880b57cec5SDimitry Andric if (want_breakpoint) { 28890b57cec5SDimitry Andric // Try to clear the breakpoint. 28900b57cec5SDimitry Andric const Status error = 2891fe6060f1SDimitry Andric m_current_process->RemoveBreakpoint(addr, want_hardware); 28920b57cec5SDimitry Andric if (error.Success()) 28930b57cec5SDimitry Andric return SendOKResponse(); 289481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Breakpoints); 28950b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to remove breakpoint: {1}", 2896fe6060f1SDimitry Andric m_current_process->GetID(), error); 28970b57cec5SDimitry Andric return SendErrorResponse(0x09); 28980b57cec5SDimitry Andric } else { 28990b57cec5SDimitry Andric // Try to clear the watchpoint. 2900fe6060f1SDimitry Andric const Status error = m_current_process->RemoveWatchpoint(addr); 29010b57cec5SDimitry Andric if (error.Success()) 29020b57cec5SDimitry Andric return SendOKResponse(); 290381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Watchpoints); 29040b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to remove watchpoint: {1}", 2905fe6060f1SDimitry Andric m_current_process->GetID(), error); 29060b57cec5SDimitry Andric return SendErrorResponse(0x09); 29070b57cec5SDimitry Andric } 29080b57cec5SDimitry Andric } 29090b57cec5SDimitry Andric 29100b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 29110b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { 291281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 29130b57cec5SDimitry Andric 29140b57cec5SDimitry Andric // Ensure we have a process. 2915fe6060f1SDimitry Andric if (!m_continue_process || 2916fe6060f1SDimitry Andric (m_continue_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 29179dba64beSDimitry Andric LLDB_LOGF( 29189dba64beSDimitry Andric log, 29190b57cec5SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 29200b57cec5SDimitry Andric __FUNCTION__); 29210b57cec5SDimitry Andric return SendErrorResponse(0x32); 29220b57cec5SDimitry Andric } 29230b57cec5SDimitry Andric 29240b57cec5SDimitry Andric // We first try to use a continue thread id. If any one or any all set, use 29250b57cec5SDimitry Andric // the current thread. Bail out if we don't have a thread id. 29260b57cec5SDimitry Andric lldb::tid_t tid = GetContinueThreadID(); 29270b57cec5SDimitry Andric if (tid == 0 || tid == LLDB_INVALID_THREAD_ID) 29280b57cec5SDimitry Andric tid = GetCurrentThreadID(); 29290b57cec5SDimitry Andric if (tid == LLDB_INVALID_THREAD_ID) 29300b57cec5SDimitry Andric return SendErrorResponse(0x33); 29310b57cec5SDimitry Andric 29320b57cec5SDimitry Andric // Double check that we have such a thread. 29330b57cec5SDimitry Andric // TODO investigate: on MacOSX we might need to do an UpdateThreads () here. 2934fe6060f1SDimitry Andric NativeThreadProtocol *thread = m_continue_process->GetThreadByID(tid); 29350b57cec5SDimitry Andric if (!thread) 29360b57cec5SDimitry Andric return SendErrorResponse(0x33); 29370b57cec5SDimitry Andric 29380b57cec5SDimitry Andric // Create the step action for the given thread. 29399dba64beSDimitry Andric ResumeAction action = {tid, eStateStepping, LLDB_INVALID_SIGNAL_NUMBER}; 29400b57cec5SDimitry Andric 29410b57cec5SDimitry Andric // Setup the actions list. 29420b57cec5SDimitry Andric ResumeActionList actions; 29430b57cec5SDimitry Andric actions.Append(action); 29440b57cec5SDimitry Andric 29450b57cec5SDimitry Andric // All other threads stop while we're single stepping a thread. 29460b57cec5SDimitry Andric actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 2947fe6060f1SDimitry Andric Status error = m_continue_process->Resume(actions); 29480b57cec5SDimitry Andric if (error.Fail()) { 29499dba64beSDimitry Andric LLDB_LOGF(log, 29509dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 29510b57cec5SDimitry Andric " tid %" PRIu64 " Resume() failed with error: %s", 2952fe6060f1SDimitry Andric __FUNCTION__, m_continue_process->GetID(), tid, 29530b57cec5SDimitry Andric error.AsCString()); 29540b57cec5SDimitry Andric return SendErrorResponse(0x49); 29550b57cec5SDimitry Andric } 29560b57cec5SDimitry Andric 295781ad6265SDimitry Andric // No response here, unless in non-stop mode. 295881ad6265SDimitry Andric // Otherwise, the stop or exit will come from the resulting action. 295981ad6265SDimitry Andric return SendContinueSuccessResponse(); 29600b57cec5SDimitry Andric } 29610b57cec5SDimitry Andric 29620b57cec5SDimitry Andric llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 29635ffd83dbSDimitry Andric GDBRemoteCommunicationServerLLGS::BuildTargetXml() { 29645ffd83dbSDimitry Andric // Ensure we have a thread. 2965fe6060f1SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0); 29665ffd83dbSDimitry Andric if (!thread) 29675ffd83dbSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 29685ffd83dbSDimitry Andric "No thread available"); 29695ffd83dbSDimitry Andric 297081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 29715ffd83dbSDimitry Andric // Get the register context for the first thread. 29725ffd83dbSDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 29735ffd83dbSDimitry Andric 29745ffd83dbSDimitry Andric StreamString response; 29755ffd83dbSDimitry Andric 29765ffd83dbSDimitry Andric response.Printf("<?xml version=\"1.0\"?>"); 29775ffd83dbSDimitry Andric response.Printf("<target version=\"1.0\">"); 29785ffd83dbSDimitry Andric 29795ffd83dbSDimitry Andric response.Printf("<architecture>%s</architecture>", 2980fe6060f1SDimitry Andric m_current_process->GetArchitecture() 29815ffd83dbSDimitry Andric .GetTriple() 29825ffd83dbSDimitry Andric .getArchName() 29835ffd83dbSDimitry Andric .str() 29845ffd83dbSDimitry Andric .c_str()); 29855ffd83dbSDimitry Andric 29865ffd83dbSDimitry Andric response.Printf("<feature>"); 29875ffd83dbSDimitry Andric 29885ffd83dbSDimitry Andric const int registers_count = reg_context.GetUserRegisterCount(); 29895ffd83dbSDimitry Andric for (int reg_index = 0; reg_index < registers_count; reg_index++) { 29905ffd83dbSDimitry Andric const RegisterInfo *reg_info = 29915ffd83dbSDimitry Andric reg_context.GetRegisterInfoAtIndex(reg_index); 29925ffd83dbSDimitry Andric 29935ffd83dbSDimitry Andric if (!reg_info) { 29945ffd83dbSDimitry Andric LLDB_LOGF(log, 29955ffd83dbSDimitry Andric "%s failed to get register info for register index %" PRIu32, 29965ffd83dbSDimitry Andric "target.xml", reg_index); 29975ffd83dbSDimitry Andric continue; 29985ffd83dbSDimitry Andric } 29995ffd83dbSDimitry Andric 3000e8d8bef9SDimitry Andric response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" regnum=\"%d\" ", 3001e8d8bef9SDimitry Andric reg_info->name, reg_info->byte_size * 8, reg_index); 3002e8d8bef9SDimitry Andric 3003e8d8bef9SDimitry Andric if (!reg_context.RegisterOffsetIsDynamic()) 3004e8d8bef9SDimitry Andric response.Printf("offset=\"%" PRIu32 "\" ", reg_info->byte_offset); 30055ffd83dbSDimitry Andric 30065ffd83dbSDimitry Andric if (reg_info->alt_name && reg_info->alt_name[0]) 30075ffd83dbSDimitry Andric response.Printf("altname=\"%s\" ", reg_info->alt_name); 30085ffd83dbSDimitry Andric 30095ffd83dbSDimitry Andric llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info); 30105ffd83dbSDimitry Andric if (!encoding.empty()) 30115ffd83dbSDimitry Andric response << "encoding=\"" << encoding << "\" "; 30125ffd83dbSDimitry Andric 30135ffd83dbSDimitry Andric llvm::StringRef format = GetFormatNameOrEmpty(*reg_info); 30145ffd83dbSDimitry Andric if (!format.empty()) 30155ffd83dbSDimitry Andric response << "format=\"" << format << "\" "; 30165ffd83dbSDimitry Andric 30175ffd83dbSDimitry Andric const char *const register_set_name = 30185ffd83dbSDimitry Andric reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); 30195ffd83dbSDimitry Andric if (register_set_name) 30205ffd83dbSDimitry Andric response << "group=\"" << register_set_name << "\" "; 30215ffd83dbSDimitry Andric 30225ffd83dbSDimitry Andric if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != 30235ffd83dbSDimitry Andric LLDB_INVALID_REGNUM) 30245ffd83dbSDimitry Andric response.Printf("ehframe_regnum=\"%" PRIu32 "\" ", 30255ffd83dbSDimitry Andric reg_info->kinds[RegisterKind::eRegisterKindEHFrame]); 30265ffd83dbSDimitry Andric 30275ffd83dbSDimitry Andric if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != 30285ffd83dbSDimitry Andric LLDB_INVALID_REGNUM) 30295ffd83dbSDimitry Andric response.Printf("dwarf_regnum=\"%" PRIu32 "\" ", 30305ffd83dbSDimitry Andric reg_info->kinds[RegisterKind::eRegisterKindDWARF]); 30315ffd83dbSDimitry Andric 30325ffd83dbSDimitry Andric llvm::StringRef kind_generic = GetKindGenericOrEmpty(*reg_info); 30335ffd83dbSDimitry Andric if (!kind_generic.empty()) 30345ffd83dbSDimitry Andric response << "generic=\"" << kind_generic << "\" "; 30355ffd83dbSDimitry Andric 30365ffd83dbSDimitry Andric if (reg_info->value_regs && 30375ffd83dbSDimitry Andric reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { 30385ffd83dbSDimitry Andric response.PutCString("value_regnums=\""); 30395ffd83dbSDimitry Andric CollectRegNums(reg_info->value_regs, response, false); 30405ffd83dbSDimitry Andric response.Printf("\" "); 30415ffd83dbSDimitry Andric } 30425ffd83dbSDimitry Andric 30435ffd83dbSDimitry Andric if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) { 30445ffd83dbSDimitry Andric response.PutCString("invalidate_regnums=\""); 30455ffd83dbSDimitry Andric CollectRegNums(reg_info->invalidate_regs, response, false); 30465ffd83dbSDimitry Andric response.Printf("\" "); 30475ffd83dbSDimitry Andric } 30485ffd83dbSDimitry Andric 30495ffd83dbSDimitry Andric response.Printf("/>"); 30505ffd83dbSDimitry Andric } 30515ffd83dbSDimitry Andric 30525ffd83dbSDimitry Andric response.Printf("</feature>"); 30535ffd83dbSDimitry Andric response.Printf("</target>"); 30545ffd83dbSDimitry Andric return MemoryBuffer::getMemBufferCopy(response.GetString(), "target.xml"); 30555ffd83dbSDimitry Andric } 30565ffd83dbSDimitry Andric 30575ffd83dbSDimitry Andric llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 30580b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object, 30590b57cec5SDimitry Andric llvm::StringRef annex) { 30600b57cec5SDimitry Andric // Make sure we have a valid process. 3061fe6060f1SDimitry Andric if (!m_current_process || 3062fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 30630b57cec5SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 30640b57cec5SDimitry Andric "No process available"); 30650b57cec5SDimitry Andric } 30660b57cec5SDimitry Andric 30675ffd83dbSDimitry Andric if (object == "auxv") { 30680b57cec5SDimitry Andric // Grab the auxv data. 3069fe6060f1SDimitry Andric auto buffer_or_error = m_current_process->GetAuxvData(); 30700b57cec5SDimitry Andric if (!buffer_or_error) 30710b57cec5SDimitry Andric return llvm::errorCodeToError(buffer_or_error.getError()); 30720b57cec5SDimitry Andric return std::move(*buffer_or_error); 30730b57cec5SDimitry Andric } 30740b57cec5SDimitry Andric 307504eeddc0SDimitry Andric if (object == "siginfo") { 307604eeddc0SDimitry Andric NativeThreadProtocol *thread = m_current_process->GetCurrentThread(); 307704eeddc0SDimitry Andric if (!thread) 307804eeddc0SDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(), 307904eeddc0SDimitry Andric "no current thread"); 308004eeddc0SDimitry Andric 308104eeddc0SDimitry Andric auto buffer_or_error = thread->GetSiginfo(); 308204eeddc0SDimitry Andric if (!buffer_or_error) 308304eeddc0SDimitry Andric return buffer_or_error.takeError(); 308404eeddc0SDimitry Andric return std::move(*buffer_or_error); 308504eeddc0SDimitry Andric } 308604eeddc0SDimitry Andric 30879dba64beSDimitry Andric if (object == "libraries-svr4") { 3088fe6060f1SDimitry Andric auto library_list = m_current_process->GetLoadedSVR4Libraries(); 30899dba64beSDimitry Andric if (!library_list) 30909dba64beSDimitry Andric return library_list.takeError(); 30919dba64beSDimitry Andric 30929dba64beSDimitry Andric StreamString response; 30939dba64beSDimitry Andric response.Printf("<library-list-svr4 version=\"1.0\">"); 30949dba64beSDimitry Andric for (auto const &library : *library_list) { 30959dba64beSDimitry Andric response.Printf("<library name=\"%s\" ", 30969dba64beSDimitry Andric XMLEncodeAttributeValue(library.name.c_str()).c_str()); 30979dba64beSDimitry Andric response.Printf("lm=\"0x%" PRIx64 "\" ", library.link_map); 30989dba64beSDimitry Andric response.Printf("l_addr=\"0x%" PRIx64 "\" ", library.base_addr); 30999dba64beSDimitry Andric response.Printf("l_ld=\"0x%" PRIx64 "\" />", library.ld_addr); 31009dba64beSDimitry Andric } 31019dba64beSDimitry Andric response.Printf("</library-list-svr4>"); 31029dba64beSDimitry Andric return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__); 31039dba64beSDimitry Andric } 31049dba64beSDimitry Andric 31055ffd83dbSDimitry Andric if (object == "features" && annex == "target.xml") 31065ffd83dbSDimitry Andric return BuildTargetXml(); 31075ffd83dbSDimitry Andric 3108e8d8bef9SDimitry Andric return llvm::make_error<UnimplementedError>(); 31090b57cec5SDimitry Andric } 31100b57cec5SDimitry Andric 31110b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 31120b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qXfer( 31130b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 31140b57cec5SDimitry Andric SmallVector<StringRef, 5> fields; 31150b57cec5SDimitry Andric // The packet format is "qXfer:<object>:<action>:<annex>:offset,length" 31160b57cec5SDimitry Andric StringRef(packet.GetStringRef()).split(fields, ':', 4); 31170b57cec5SDimitry Andric if (fields.size() != 5) 31180b57cec5SDimitry Andric return SendIllFormedResponse(packet, "malformed qXfer packet"); 31190b57cec5SDimitry Andric StringRef &xfer_object = fields[1]; 31200b57cec5SDimitry Andric StringRef &xfer_action = fields[2]; 31210b57cec5SDimitry Andric StringRef &xfer_annex = fields[3]; 31220b57cec5SDimitry Andric StringExtractor offset_data(fields[4]); 31230b57cec5SDimitry Andric if (xfer_action != "read") 31240b57cec5SDimitry Andric return SendUnimplementedResponse("qXfer action not supported"); 31250b57cec5SDimitry Andric // Parse offset. 31260b57cec5SDimitry Andric const uint64_t xfer_offset = 31270b57cec5SDimitry Andric offset_data.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max()); 31280b57cec5SDimitry Andric if (xfer_offset == std::numeric_limits<uint64_t>::max()) 31290b57cec5SDimitry Andric return SendIllFormedResponse(packet, "qXfer packet missing offset"); 31300b57cec5SDimitry Andric // Parse out comma. 31310b57cec5SDimitry Andric if (offset_data.GetChar() != ',') 31320b57cec5SDimitry Andric return SendIllFormedResponse(packet, 31330b57cec5SDimitry Andric "qXfer packet missing comma after offset"); 31340b57cec5SDimitry Andric // Parse out the length. 31350b57cec5SDimitry Andric const uint64_t xfer_length = 31360b57cec5SDimitry Andric offset_data.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max()); 31370b57cec5SDimitry Andric if (xfer_length == std::numeric_limits<uint64_t>::max()) 31380b57cec5SDimitry Andric return SendIllFormedResponse(packet, "qXfer packet missing length"); 31390b57cec5SDimitry Andric 31400b57cec5SDimitry Andric // Get a previously constructed buffer if it exists or create it now. 31410b57cec5SDimitry Andric std::string buffer_key = (xfer_object + xfer_action + xfer_annex).str(); 31420b57cec5SDimitry Andric auto buffer_it = m_xfer_buffer_map.find(buffer_key); 31430b57cec5SDimitry Andric if (buffer_it == m_xfer_buffer_map.end()) { 31440b57cec5SDimitry Andric auto buffer_up = ReadXferObject(xfer_object, xfer_annex); 31450b57cec5SDimitry Andric if (!buffer_up) 31460b57cec5SDimitry Andric return SendErrorResponse(buffer_up.takeError()); 31470b57cec5SDimitry Andric buffer_it = m_xfer_buffer_map 31480b57cec5SDimitry Andric .insert(std::make_pair(buffer_key, std::move(*buffer_up))) 31490b57cec5SDimitry Andric .first; 31500b57cec5SDimitry Andric } 31510b57cec5SDimitry Andric 31520b57cec5SDimitry Andric // Send back the response 31530b57cec5SDimitry Andric StreamGDBRemote response; 31540b57cec5SDimitry Andric bool done_with_buffer = false; 31550b57cec5SDimitry Andric llvm::StringRef buffer = buffer_it->second->getBuffer(); 31560b57cec5SDimitry Andric if (xfer_offset >= buffer.size()) { 31570b57cec5SDimitry Andric // We have nothing left to send. Mark the buffer as complete. 31580b57cec5SDimitry Andric response.PutChar('l'); 31590b57cec5SDimitry Andric done_with_buffer = true; 31600b57cec5SDimitry Andric } else { 31610b57cec5SDimitry Andric // Figure out how many bytes are available starting at the given offset. 31620b57cec5SDimitry Andric buffer = buffer.drop_front(xfer_offset); 31630b57cec5SDimitry Andric // Mark the response type according to whether we're reading the remainder 31640b57cec5SDimitry Andric // of the data. 31650b57cec5SDimitry Andric if (xfer_length >= buffer.size()) { 31660b57cec5SDimitry Andric // There will be nothing left to read after this 31670b57cec5SDimitry Andric response.PutChar('l'); 31680b57cec5SDimitry Andric done_with_buffer = true; 31690b57cec5SDimitry Andric } else { 31700b57cec5SDimitry Andric // There will still be bytes to read after this request. 31710b57cec5SDimitry Andric response.PutChar('m'); 31720b57cec5SDimitry Andric buffer = buffer.take_front(xfer_length); 31730b57cec5SDimitry Andric } 31740b57cec5SDimitry Andric // Now write the data in encoded binary form. 31750b57cec5SDimitry Andric response.PutEscapedBytes(buffer.data(), buffer.size()); 31760b57cec5SDimitry Andric } 31770b57cec5SDimitry Andric 31780b57cec5SDimitry Andric if (done_with_buffer) 31790b57cec5SDimitry Andric m_xfer_buffer_map.erase(buffer_it); 31800b57cec5SDimitry Andric 31810b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 31820b57cec5SDimitry Andric } 31830b57cec5SDimitry Andric 31840b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 31850b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( 31860b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 318781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 31880b57cec5SDimitry Andric 31890b57cec5SDimitry Andric // Move past packet name. 31900b57cec5SDimitry Andric packet.SetFilePos(strlen("QSaveRegisterState")); 31910b57cec5SDimitry Andric 31920b57cec5SDimitry Andric // Get the thread to use. 31930b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 31940b57cec5SDimitry Andric if (!thread) { 31950b57cec5SDimitry Andric if (m_thread_suffix_supported) 31960b57cec5SDimitry Andric return SendIllFormedResponse( 31970b57cec5SDimitry Andric packet, "No thread specified in QSaveRegisterState packet"); 31980b57cec5SDimitry Andric else 31990b57cec5SDimitry Andric return SendIllFormedResponse(packet, 32000b57cec5SDimitry Andric "No thread was is set with the Hg packet"); 32010b57cec5SDimitry Andric } 32020b57cec5SDimitry Andric 32030b57cec5SDimitry Andric // Grab the register context for the thread. 32040b57cec5SDimitry Andric NativeRegisterContext& reg_context = thread->GetRegisterContext(); 32050b57cec5SDimitry Andric 32060b57cec5SDimitry Andric // Save registers to a buffer. 320781ad6265SDimitry Andric WritableDataBufferSP register_data_sp; 32080b57cec5SDimitry Andric Status error = reg_context.ReadAllRegisterValues(register_data_sp); 32090b57cec5SDimitry Andric if (error.Fail()) { 32100b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to save all register values: {1}", 3211fe6060f1SDimitry Andric m_current_process->GetID(), error); 32120b57cec5SDimitry Andric return SendErrorResponse(0x75); 32130b57cec5SDimitry Andric } 32140b57cec5SDimitry Andric 32150b57cec5SDimitry Andric // Allocate a new save id. 32160b57cec5SDimitry Andric const uint32_t save_id = GetNextSavedRegistersID(); 32170b57cec5SDimitry Andric assert((m_saved_registers_map.find(save_id) == m_saved_registers_map.end()) && 32180b57cec5SDimitry Andric "GetNextRegisterSaveID() returned an existing register save id"); 32190b57cec5SDimitry Andric 32200b57cec5SDimitry Andric // Save the register data buffer under the save id. 32210b57cec5SDimitry Andric { 32220b57cec5SDimitry Andric std::lock_guard<std::mutex> guard(m_saved_registers_mutex); 32230b57cec5SDimitry Andric m_saved_registers_map[save_id] = register_data_sp; 32240b57cec5SDimitry Andric } 32250b57cec5SDimitry Andric 32260b57cec5SDimitry Andric // Write the response. 32270b57cec5SDimitry Andric StreamGDBRemote response; 32280b57cec5SDimitry Andric response.Printf("%" PRIu32, save_id); 32290b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 32300b57cec5SDimitry Andric } 32310b57cec5SDimitry Andric 32320b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 32330b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( 32340b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 323581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 32360b57cec5SDimitry Andric 32370b57cec5SDimitry Andric // Parse out save id. 32380b57cec5SDimitry Andric packet.SetFilePos(strlen("QRestoreRegisterState:")); 32390b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1) 32400b57cec5SDimitry Andric return SendIllFormedResponse( 32410b57cec5SDimitry Andric packet, "QRestoreRegisterState packet missing register save id"); 32420b57cec5SDimitry Andric 32430b57cec5SDimitry Andric const uint32_t save_id = packet.GetU32(0); 32440b57cec5SDimitry Andric if (save_id == 0) { 32450b57cec5SDimitry Andric LLDB_LOG(log, "QRestoreRegisterState packet has malformed save id, " 32460b57cec5SDimitry Andric "expecting decimal uint32_t"); 32470b57cec5SDimitry Andric return SendErrorResponse(0x76); 32480b57cec5SDimitry Andric } 32490b57cec5SDimitry Andric 32500b57cec5SDimitry Andric // Get the thread to use. 32510b57cec5SDimitry Andric NativeThreadProtocol *thread = GetThreadFromSuffix(packet); 32520b57cec5SDimitry Andric if (!thread) { 32530b57cec5SDimitry Andric if (m_thread_suffix_supported) 32540b57cec5SDimitry Andric return SendIllFormedResponse( 32550b57cec5SDimitry Andric packet, "No thread specified in QRestoreRegisterState packet"); 32560b57cec5SDimitry Andric else 32570b57cec5SDimitry Andric return SendIllFormedResponse(packet, 32580b57cec5SDimitry Andric "No thread was is set with the Hg packet"); 32590b57cec5SDimitry Andric } 32600b57cec5SDimitry Andric 32610b57cec5SDimitry Andric // Grab the register context for the thread. 32620b57cec5SDimitry Andric NativeRegisterContext ®_context = thread->GetRegisterContext(); 32630b57cec5SDimitry Andric 32640b57cec5SDimitry Andric // Retrieve register state buffer, then remove from the list. 32650b57cec5SDimitry Andric DataBufferSP register_data_sp; 32660b57cec5SDimitry Andric { 32670b57cec5SDimitry Andric std::lock_guard<std::mutex> guard(m_saved_registers_mutex); 32680b57cec5SDimitry Andric 32690b57cec5SDimitry Andric // Find the register set buffer for the given save id. 32700b57cec5SDimitry Andric auto it = m_saved_registers_map.find(save_id); 32710b57cec5SDimitry Andric if (it == m_saved_registers_map.end()) { 32720b57cec5SDimitry Andric LLDB_LOG(log, 32730b57cec5SDimitry Andric "pid {0} does not have a register set save buffer for id {1}", 3274fe6060f1SDimitry Andric m_current_process->GetID(), save_id); 32750b57cec5SDimitry Andric return SendErrorResponse(0x77); 32760b57cec5SDimitry Andric } 32770b57cec5SDimitry Andric register_data_sp = it->second; 32780b57cec5SDimitry Andric 32790b57cec5SDimitry Andric // Remove it from the map. 32800b57cec5SDimitry Andric m_saved_registers_map.erase(it); 32810b57cec5SDimitry Andric } 32820b57cec5SDimitry Andric 32830b57cec5SDimitry Andric Status error = reg_context.WriteAllRegisterValues(register_data_sp); 32840b57cec5SDimitry Andric if (error.Fail()) { 32850b57cec5SDimitry Andric LLDB_LOG(log, "pid {0} failed to restore all register values: {1}", 3286fe6060f1SDimitry Andric m_current_process->GetID(), error); 32870b57cec5SDimitry Andric return SendErrorResponse(0x77); 32880b57cec5SDimitry Andric } 32890b57cec5SDimitry Andric 32900b57cec5SDimitry Andric return SendOKResponse(); 32910b57cec5SDimitry Andric } 32920b57cec5SDimitry Andric 32930b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 32940b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vAttach( 32950b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 329681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 32970b57cec5SDimitry Andric 32980b57cec5SDimitry Andric // Consume the ';' after vAttach. 32990b57cec5SDimitry Andric packet.SetFilePos(strlen("vAttach")); 33000b57cec5SDimitry Andric if (!packet.GetBytesLeft() || packet.GetChar() != ';') 33010b57cec5SDimitry Andric return SendIllFormedResponse(packet, "vAttach missing expected ';'"); 33020b57cec5SDimitry Andric 33030b57cec5SDimitry Andric // Grab the PID to which we will attach (assume hex encoding). 33040b57cec5SDimitry Andric lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); 33050b57cec5SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 33060b57cec5SDimitry Andric return SendIllFormedResponse(packet, 33070b57cec5SDimitry Andric "vAttach failed to parse the process id"); 33080b57cec5SDimitry Andric 33090b57cec5SDimitry Andric // Attempt to attach. 33109dba64beSDimitry Andric LLDB_LOGF(log, 33119dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s attempting to attach to " 33120b57cec5SDimitry Andric "pid %" PRIu64, 33130b57cec5SDimitry Andric __FUNCTION__, pid); 33140b57cec5SDimitry Andric 33150b57cec5SDimitry Andric Status error = AttachToProcess(pid); 33160b57cec5SDimitry Andric 33170b57cec5SDimitry Andric if (error.Fail()) { 33189dba64beSDimitry Andric LLDB_LOGF(log, 33199dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed to attach to " 33200b57cec5SDimitry Andric "pid %" PRIu64 ": %s\n", 33210b57cec5SDimitry Andric __FUNCTION__, pid, error.AsCString()); 33220b57cec5SDimitry Andric return SendErrorResponse(error); 33230b57cec5SDimitry Andric } 33240b57cec5SDimitry Andric 33250b57cec5SDimitry Andric // Notify we attached by sending a stop packet. 332681ad6265SDimitry Andric assert(m_current_process); 332781ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 332881ad6265SDimitry Andric m_current_process->GetState(), 332981ad6265SDimitry Andric /*force_synchronous=*/false); 33300b57cec5SDimitry Andric } 33310b57cec5SDimitry Andric 33320b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 3333e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vAttachWait( 3334e8d8bef9SDimitry Andric StringExtractorGDBRemote &packet) { 333581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3336e8d8bef9SDimitry Andric 3337e8d8bef9SDimitry Andric // Consume the ';' after the identifier. 3338e8d8bef9SDimitry Andric packet.SetFilePos(strlen("vAttachWait")); 3339e8d8bef9SDimitry Andric 3340e8d8bef9SDimitry Andric if (!packet.GetBytesLeft() || packet.GetChar() != ';') 3341e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "vAttachWait missing expected ';'"); 3342e8d8bef9SDimitry Andric 3343e8d8bef9SDimitry Andric // Allocate the buffer for the process name from vAttachWait. 3344e8d8bef9SDimitry Andric std::string process_name; 3345e8d8bef9SDimitry Andric if (!packet.GetHexByteString(process_name)) 3346e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, 3347e8d8bef9SDimitry Andric "vAttachWait failed to parse process name"); 3348e8d8bef9SDimitry Andric 3349e8d8bef9SDimitry Andric LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name); 3350e8d8bef9SDimitry Andric 3351e8d8bef9SDimitry Andric Status error = AttachWaitProcess(process_name, false); 3352e8d8bef9SDimitry Andric if (error.Fail()) { 3353e8d8bef9SDimitry Andric LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name, 3354e8d8bef9SDimitry Andric error); 3355e8d8bef9SDimitry Andric return SendErrorResponse(error); 3356e8d8bef9SDimitry Andric } 3357e8d8bef9SDimitry Andric 3358e8d8bef9SDimitry Andric // Notify we attached by sending a stop packet. 335981ad6265SDimitry Andric assert(m_current_process); 336081ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 336181ad6265SDimitry Andric m_current_process->GetState(), 336281ad6265SDimitry Andric /*force_synchronous=*/false); 3363e8d8bef9SDimitry Andric } 3364e8d8bef9SDimitry Andric 3365e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 3366e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported( 3367e8d8bef9SDimitry Andric StringExtractorGDBRemote &packet) { 3368e8d8bef9SDimitry Andric return SendOKResponse(); 3369e8d8bef9SDimitry Andric } 3370e8d8bef9SDimitry Andric 3371e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 3372e8d8bef9SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait( 3373e8d8bef9SDimitry Andric StringExtractorGDBRemote &packet) { 337481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3375e8d8bef9SDimitry Andric 3376e8d8bef9SDimitry Andric // Consume the ';' after the identifier. 3377e8d8bef9SDimitry Andric packet.SetFilePos(strlen("vAttachOrWait")); 3378e8d8bef9SDimitry Andric 3379e8d8bef9SDimitry Andric if (!packet.GetBytesLeft() || packet.GetChar() != ';') 3380e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, "vAttachOrWait missing expected ';'"); 3381e8d8bef9SDimitry Andric 3382e8d8bef9SDimitry Andric // Allocate the buffer for the process name from vAttachWait. 3383e8d8bef9SDimitry Andric std::string process_name; 3384e8d8bef9SDimitry Andric if (!packet.GetHexByteString(process_name)) 3385e8d8bef9SDimitry Andric return SendIllFormedResponse(packet, 3386e8d8bef9SDimitry Andric "vAttachOrWait failed to parse process name"); 3387e8d8bef9SDimitry Andric 3388e8d8bef9SDimitry Andric LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name); 3389e8d8bef9SDimitry Andric 3390e8d8bef9SDimitry Andric Status error = AttachWaitProcess(process_name, true); 3391e8d8bef9SDimitry Andric if (error.Fail()) { 3392e8d8bef9SDimitry Andric LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name, 3393e8d8bef9SDimitry Andric error); 3394e8d8bef9SDimitry Andric return SendErrorResponse(error); 3395e8d8bef9SDimitry Andric } 3396e8d8bef9SDimitry Andric 3397e8d8bef9SDimitry Andric // Notify we attached by sending a stop packet. 339881ad6265SDimitry Andric assert(m_current_process); 339981ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 340081ad6265SDimitry Andric m_current_process->GetState(), 340181ad6265SDimitry Andric /*force_synchronous=*/false); 3402e8d8bef9SDimitry Andric } 3403e8d8bef9SDimitry Andric 3404e8d8bef9SDimitry Andric GDBRemoteCommunication::PacketResult 3405349cc55cSDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vRun( 3406349cc55cSDimitry Andric StringExtractorGDBRemote &packet) { 340781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3408349cc55cSDimitry Andric 3409349cc55cSDimitry Andric llvm::StringRef s = packet.GetStringRef(); 3410349cc55cSDimitry Andric if (!s.consume_front("vRun;")) 3411349cc55cSDimitry Andric return SendErrorResponse(8); 3412349cc55cSDimitry Andric 3413349cc55cSDimitry Andric llvm::SmallVector<llvm::StringRef, 16> argv; 3414349cc55cSDimitry Andric s.split(argv, ';'); 3415349cc55cSDimitry Andric 3416349cc55cSDimitry Andric for (llvm::StringRef hex_arg : argv) { 3417349cc55cSDimitry Andric StringExtractor arg_ext{hex_arg}; 3418349cc55cSDimitry Andric std::string arg; 3419349cc55cSDimitry Andric arg_ext.GetHexByteString(arg); 3420349cc55cSDimitry Andric m_process_launch_info.GetArguments().AppendArgument(arg); 3421349cc55cSDimitry Andric LLDB_LOGF(log, "LLGSPacketHandler::%s added arg: \"%s\"", __FUNCTION__, 3422349cc55cSDimitry Andric arg.c_str()); 3423349cc55cSDimitry Andric } 3424349cc55cSDimitry Andric 3425349cc55cSDimitry Andric if (!argv.empty()) { 3426349cc55cSDimitry Andric m_process_launch_info.GetExecutableFile().SetFile( 3427349cc55cSDimitry Andric m_process_launch_info.GetArguments()[0].ref(), FileSpec::Style::native); 3428349cc55cSDimitry Andric m_process_launch_error = LaunchProcess(); 342981ad6265SDimitry Andric if (m_process_launch_error.Success()) { 343081ad6265SDimitry Andric assert(m_current_process); 343181ad6265SDimitry Andric return SendStopReasonForState(*m_current_process, 343281ad6265SDimitry Andric m_current_process->GetState(), 343381ad6265SDimitry Andric /*force_synchronous=*/true); 343481ad6265SDimitry Andric } 3435349cc55cSDimitry Andric LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error); 3436349cc55cSDimitry Andric } 3437349cc55cSDimitry Andric return SendErrorResponse(8); 3438349cc55cSDimitry Andric } 3439349cc55cSDimitry Andric 3440349cc55cSDimitry Andric GDBRemoteCommunication::PacketResult 34410b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { 344281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 34430b57cec5SDimitry Andric StopSTDIOForwarding(); 34440b57cec5SDimitry Andric 34450b57cec5SDimitry Andric lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 34460b57cec5SDimitry Andric 34470b57cec5SDimitry Andric // Consume the ';' after D. 34480b57cec5SDimitry Andric packet.SetFilePos(1); 34490b57cec5SDimitry Andric if (packet.GetBytesLeft()) { 34500b57cec5SDimitry Andric if (packet.GetChar() != ';') 34510b57cec5SDimitry Andric return SendIllFormedResponse(packet, "D missing expected ';'"); 34520b57cec5SDimitry Andric 34530b57cec5SDimitry Andric // Grab the PID from which we will detach (assume hex encoding). 34540b57cec5SDimitry Andric pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16); 34550b57cec5SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 34560b57cec5SDimitry Andric return SendIllFormedResponse(packet, "D failed to parse the process id"); 34570b57cec5SDimitry Andric } 34580b57cec5SDimitry Andric 3459fe6060f1SDimitry Andric // Detach forked children if their PID was specified *or* no PID was requested 3460fe6060f1SDimitry Andric // (i.e. detach-all packet). 3461fe6060f1SDimitry Andric llvm::Error detach_error = llvm::Error::success(); 3462fe6060f1SDimitry Andric bool detached = false; 3463fe6060f1SDimitry Andric for (auto it = m_debugged_processes.begin(); 3464fe6060f1SDimitry Andric it != m_debugged_processes.end();) { 3465fe6060f1SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID || pid == it->first) { 346681ad6265SDimitry Andric LLDB_LOGF(log, 346781ad6265SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s detaching %" PRId64, 346881ad6265SDimitry Andric __FUNCTION__, it->first); 3469fe6060f1SDimitry Andric if (llvm::Error e = it->second->Detach().ToError()) 3470fe6060f1SDimitry Andric detach_error = llvm::joinErrors(std::move(detach_error), std::move(e)); 3471fe6060f1SDimitry Andric else { 3472fe6060f1SDimitry Andric if (it->second.get() == m_current_process) 3473fe6060f1SDimitry Andric m_current_process = nullptr; 3474fe6060f1SDimitry Andric if (it->second.get() == m_continue_process) 3475fe6060f1SDimitry Andric m_continue_process = nullptr; 3476fe6060f1SDimitry Andric it = m_debugged_processes.erase(it); 3477fe6060f1SDimitry Andric detached = true; 3478fe6060f1SDimitry Andric continue; 3479fe6060f1SDimitry Andric } 3480fe6060f1SDimitry Andric } 3481fe6060f1SDimitry Andric ++it; 34820b57cec5SDimitry Andric } 34830b57cec5SDimitry Andric 3484fe6060f1SDimitry Andric if (detach_error) 3485fe6060f1SDimitry Andric return SendErrorResponse(std::move(detach_error)); 3486fe6060f1SDimitry Andric if (!detached) 3487fe6060f1SDimitry Andric return SendErrorResponse(Status("PID %" PRIu64 " not traced", pid)); 34880b57cec5SDimitry Andric return SendOKResponse(); 34890b57cec5SDimitry Andric } 34900b57cec5SDimitry Andric 34910b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 34920b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo( 34930b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 349481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 349581ad6265SDimitry Andric 349681ad6265SDimitry Andric if (!m_current_process || 349781ad6265SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 349881ad6265SDimitry Andric return SendErrorResponse(50); 34990b57cec5SDimitry Andric 35000b57cec5SDimitry Andric packet.SetFilePos(strlen("qThreadStopInfo")); 3501fe6060f1SDimitry Andric const lldb::tid_t tid = packet.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID); 35020b57cec5SDimitry Andric if (tid == LLDB_INVALID_THREAD_ID) { 35039dba64beSDimitry Andric LLDB_LOGF(log, 35049dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, could not " 35050b57cec5SDimitry Andric "parse thread id from request \"%s\"", 35069dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 35070b57cec5SDimitry Andric return SendErrorResponse(0x15); 35080b57cec5SDimitry Andric } 350981ad6265SDimitry Andric return SendStopReplyPacketForThread(*m_current_process, tid, 351081ad6265SDimitry Andric /*force_synchronous=*/true); 35110b57cec5SDimitry Andric } 35120b57cec5SDimitry Andric 35130b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 35140b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo( 35150b57cec5SDimitry Andric StringExtractorGDBRemote &) { 351681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread); 35170b57cec5SDimitry Andric 35180b57cec5SDimitry Andric // Ensure we have a debugged process. 3519fe6060f1SDimitry Andric if (!m_current_process || 3520fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 35210b57cec5SDimitry Andric return SendErrorResponse(50); 3522fe6060f1SDimitry Andric LLDB_LOG(log, "preparing packet for pid {0}", m_current_process->GetID()); 35230b57cec5SDimitry Andric 35240b57cec5SDimitry Andric StreamString response; 35250b57cec5SDimitry Andric const bool threads_with_valid_stop_info_only = false; 3526fe6060f1SDimitry Andric llvm::Expected<json::Value> threads_info = 3527fe6060f1SDimitry Andric GetJSONThreadsInfo(*m_current_process, threads_with_valid_stop_info_only); 35289dba64beSDimitry Andric if (!threads_info) { 3529480093f4SDimitry Andric LLDB_LOG_ERROR(log, threads_info.takeError(), 3530480093f4SDimitry Andric "failed to prepare a packet for pid {1}: {0}", 3531fe6060f1SDimitry Andric m_current_process->GetID()); 35320b57cec5SDimitry Andric return SendErrorResponse(52); 35330b57cec5SDimitry Andric } 35340b57cec5SDimitry Andric 35359dba64beSDimitry Andric response.AsRawOstream() << *threads_info; 35360b57cec5SDimitry Andric StreamGDBRemote escaped_response; 35370b57cec5SDimitry Andric escaped_response.PutEscapedBytes(response.GetData(), response.GetSize()); 35380b57cec5SDimitry Andric return SendPacketNoLock(escaped_response.GetString()); 35390b57cec5SDimitry Andric } 35400b57cec5SDimitry Andric 35410b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 35420b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo( 35430b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 35440b57cec5SDimitry Andric // Fail if we don't have a current process. 3545fe6060f1SDimitry Andric if (!m_current_process || 3546fe6060f1SDimitry Andric m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) 35470b57cec5SDimitry Andric return SendErrorResponse(68); 35480b57cec5SDimitry Andric 35490b57cec5SDimitry Andric packet.SetFilePos(strlen("qWatchpointSupportInfo")); 35500b57cec5SDimitry Andric if (packet.GetBytesLeft() == 0) 35510b57cec5SDimitry Andric return SendOKResponse(); 35520b57cec5SDimitry Andric if (packet.GetChar() != ':') 35530b57cec5SDimitry Andric return SendErrorResponse(67); 35540b57cec5SDimitry Andric 3555fe6060f1SDimitry Andric auto hw_debug_cap = m_current_process->GetHardwareDebugSupportInfo(); 35560b57cec5SDimitry Andric 35570b57cec5SDimitry Andric StreamGDBRemote response; 35580b57cec5SDimitry Andric if (hw_debug_cap == llvm::None) 35590b57cec5SDimitry Andric response.Printf("num:0;"); 35600b57cec5SDimitry Andric else 35610b57cec5SDimitry Andric response.Printf("num:%d;", hw_debug_cap->second); 35620b57cec5SDimitry Andric 35630b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 35640b57cec5SDimitry Andric } 35650b57cec5SDimitry Andric 35660b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 35670b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress( 35680b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 35690b57cec5SDimitry Andric // Fail if we don't have a current process. 3570fe6060f1SDimitry Andric if (!m_current_process || 3571fe6060f1SDimitry Andric m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) 35720b57cec5SDimitry Andric return SendErrorResponse(67); 35730b57cec5SDimitry Andric 35740b57cec5SDimitry Andric packet.SetFilePos(strlen("qFileLoadAddress:")); 35750b57cec5SDimitry Andric if (packet.GetBytesLeft() == 0) 35760b57cec5SDimitry Andric return SendErrorResponse(68); 35770b57cec5SDimitry Andric 35780b57cec5SDimitry Andric std::string file_name; 35790b57cec5SDimitry Andric packet.GetHexByteString(file_name); 35800b57cec5SDimitry Andric 35810b57cec5SDimitry Andric lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS; 35820b57cec5SDimitry Andric Status error = 3583fe6060f1SDimitry Andric m_current_process->GetFileLoadAddress(file_name, file_load_address); 35840b57cec5SDimitry Andric if (error.Fail()) 35850b57cec5SDimitry Andric return SendErrorResponse(69); 35860b57cec5SDimitry Andric 35870b57cec5SDimitry Andric if (file_load_address == LLDB_INVALID_ADDRESS) 35880b57cec5SDimitry Andric return SendErrorResponse(1); // File not loaded 35890b57cec5SDimitry Andric 35900b57cec5SDimitry Andric StreamGDBRemote response; 35910b57cec5SDimitry Andric response.PutHex64(file_load_address); 35920b57cec5SDimitry Andric return SendPacketNoLock(response.GetString()); 35930b57cec5SDimitry Andric } 35940b57cec5SDimitry Andric 35950b57cec5SDimitry Andric GDBRemoteCommunication::PacketResult 35960b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QPassSignals( 35970b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 35980b57cec5SDimitry Andric std::vector<int> signals; 35990b57cec5SDimitry Andric packet.SetFilePos(strlen("QPassSignals:")); 36000b57cec5SDimitry Andric 36010b57cec5SDimitry Andric // Read sequence of hex signal numbers divided by a semicolon and optionally 36020b57cec5SDimitry Andric // spaces. 36030b57cec5SDimitry Andric while (packet.GetBytesLeft() > 0) { 36040b57cec5SDimitry Andric int signal = packet.GetS32(-1, 16); 36050b57cec5SDimitry Andric if (signal < 0) 36060b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Failed to parse signal number."); 36070b57cec5SDimitry Andric signals.push_back(signal); 36080b57cec5SDimitry Andric 36090b57cec5SDimitry Andric packet.SkipSpaces(); 36100b57cec5SDimitry Andric char separator = packet.GetChar(); 36110b57cec5SDimitry Andric if (separator == '\0') 36120b57cec5SDimitry Andric break; // End of string 36130b57cec5SDimitry Andric if (separator != ';') 36140b57cec5SDimitry Andric return SendIllFormedResponse(packet, "Invalid separator," 36150b57cec5SDimitry Andric " expected semicolon."); 36160b57cec5SDimitry Andric } 36170b57cec5SDimitry Andric 36180b57cec5SDimitry Andric // Fail if we don't have a current process. 3619fe6060f1SDimitry Andric if (!m_current_process) 36200b57cec5SDimitry Andric return SendErrorResponse(68); 36210b57cec5SDimitry Andric 3622fe6060f1SDimitry Andric Status error = m_current_process->IgnoreSignals(signals); 36230b57cec5SDimitry Andric if (error.Fail()) 36240b57cec5SDimitry Andric return SendErrorResponse(69); 36250b57cec5SDimitry Andric 36260b57cec5SDimitry Andric return SendOKResponse(); 36270b57cec5SDimitry Andric } 36280b57cec5SDimitry Andric 3629fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult 3630fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qMemTags( 3631fe6060f1SDimitry Andric StringExtractorGDBRemote &packet) { 363281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3633fe6060f1SDimitry Andric 3634fe6060f1SDimitry Andric // Ensure we have a process. 3635fe6060f1SDimitry Andric if (!m_current_process || 3636fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 3637fe6060f1SDimitry Andric LLDB_LOGF( 3638fe6060f1SDimitry Andric log, 3639fe6060f1SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 3640fe6060f1SDimitry Andric __FUNCTION__); 3641fe6060f1SDimitry Andric return SendErrorResponse(1); 3642fe6060f1SDimitry Andric } 3643fe6060f1SDimitry Andric 3644fe6060f1SDimitry Andric // We are expecting 3645fe6060f1SDimitry Andric // qMemTags:<hex address>,<hex length>:<hex type> 3646fe6060f1SDimitry Andric 3647fe6060f1SDimitry Andric // Address 3648fe6060f1SDimitry Andric packet.SetFilePos(strlen("qMemTags:")); 3649fe6060f1SDimitry Andric const char *current_char = packet.Peek(); 3650fe6060f1SDimitry Andric if (!current_char || *current_char == ',') 3651fe6060f1SDimitry Andric return SendIllFormedResponse(packet, "Missing address in qMemTags packet"); 3652fe6060f1SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0); 3653fe6060f1SDimitry Andric 3654fe6060f1SDimitry Andric // Length 3655fe6060f1SDimitry Andric char previous_char = packet.GetChar(); 3656fe6060f1SDimitry Andric current_char = packet.Peek(); 3657fe6060f1SDimitry Andric // If we don't have a separator or the length field is empty 3658fe6060f1SDimitry Andric if (previous_char != ',' || (current_char && *current_char == ':')) 3659fe6060f1SDimitry Andric return SendIllFormedResponse(packet, 3660fe6060f1SDimitry Andric "Invalid addr,length pair in qMemTags packet"); 3661fe6060f1SDimitry Andric 3662fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1) 3663fe6060f1SDimitry Andric return SendIllFormedResponse( 3664fe6060f1SDimitry Andric packet, "Too short qMemtags: packet (looking for length)"); 3665fe6060f1SDimitry Andric const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0); 3666fe6060f1SDimitry Andric 3667fe6060f1SDimitry Andric // Type 3668fe6060f1SDimitry Andric const char *invalid_type_err = "Invalid type field in qMemTags: packet"; 3669fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') 3670fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 3671fe6060f1SDimitry Andric 36726e75b2fbSDimitry Andric // Type is a signed integer but packed into the packet as its raw bytes. 36736e75b2fbSDimitry Andric // However, our GetU64 uses strtoull which allows +/-. We do not want this. 36746e75b2fbSDimitry Andric const char *first_type_char = packet.Peek(); 36756e75b2fbSDimitry Andric if (first_type_char && (*first_type_char == '+' || *first_type_char == '-')) 36766e75b2fbSDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 36776e75b2fbSDimitry Andric 36786e75b2fbSDimitry Andric // Extract type as unsigned then cast to signed. 36796e75b2fbSDimitry Andric // Using a uint64_t here so that we have some value outside of the 32 bit 36806e75b2fbSDimitry Andric // range to use as the invalid return value. 36816e75b2fbSDimitry Andric uint64_t raw_type = 36826e75b2fbSDimitry Andric packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16); 36836e75b2fbSDimitry Andric 36846e75b2fbSDimitry Andric if ( // Make sure the cast below would be valid 36856e75b2fbSDimitry Andric raw_type > std::numeric_limits<uint32_t>::max() || 3686fe6060f1SDimitry Andric // To catch inputs like "123aardvark" that will parse but clearly aren't 3687fe6060f1SDimitry Andric // valid in this case. 3688fe6060f1SDimitry Andric packet.GetBytesLeft()) { 3689fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 3690fe6060f1SDimitry Andric } 3691fe6060f1SDimitry Andric 36926e75b2fbSDimitry Andric // First narrow to 32 bits otherwise the copy into type would take 36936e75b2fbSDimitry Andric // the wrong 4 bytes on big endian. 36946e75b2fbSDimitry Andric uint32_t raw_type_32 = raw_type; 36956e75b2fbSDimitry Andric int32_t type = reinterpret_cast<int32_t &>(raw_type_32); 36966e75b2fbSDimitry Andric 3697fe6060f1SDimitry Andric StreamGDBRemote response; 3698fe6060f1SDimitry Andric std::vector<uint8_t> tags; 3699fe6060f1SDimitry Andric Status error = m_current_process->ReadMemoryTags(type, addr, length, tags); 3700fe6060f1SDimitry Andric if (error.Fail()) 3701fe6060f1SDimitry Andric return SendErrorResponse(1); 3702fe6060f1SDimitry Andric 3703fe6060f1SDimitry Andric // This m is here in case we want to support multi part replies in the future. 3704fe6060f1SDimitry Andric // In the same manner as qfThreadInfo/qsThreadInfo. 3705fe6060f1SDimitry Andric response.PutChar('m'); 3706fe6060f1SDimitry Andric response.PutBytesAsRawHex8(tags.data(), tags.size()); 3707fe6060f1SDimitry Andric return SendPacketNoLock(response.GetString()); 3708fe6060f1SDimitry Andric } 3709fe6060f1SDimitry Andric 3710fe6060f1SDimitry Andric GDBRemoteCommunication::PacketResult 3711fe6060f1SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QMemTags( 3712fe6060f1SDimitry Andric StringExtractorGDBRemote &packet) { 371381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 3714fe6060f1SDimitry Andric 3715fe6060f1SDimitry Andric // Ensure we have a process. 3716fe6060f1SDimitry Andric if (!m_current_process || 3717fe6060f1SDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) { 3718fe6060f1SDimitry Andric LLDB_LOGF( 3719fe6060f1SDimitry Andric log, 3720fe6060f1SDimitry Andric "GDBRemoteCommunicationServerLLGS::%s failed, no process available", 3721fe6060f1SDimitry Andric __FUNCTION__); 3722fe6060f1SDimitry Andric return SendErrorResponse(1); 3723fe6060f1SDimitry Andric } 3724fe6060f1SDimitry Andric 3725fe6060f1SDimitry Andric // We are expecting 3726fe6060f1SDimitry Andric // QMemTags:<hex address>,<hex length>:<hex type>:<tags as hex bytes> 3727fe6060f1SDimitry Andric 3728fe6060f1SDimitry Andric // Address 3729fe6060f1SDimitry Andric packet.SetFilePos(strlen("QMemTags:")); 3730fe6060f1SDimitry Andric const char *current_char = packet.Peek(); 3731fe6060f1SDimitry Andric if (!current_char || *current_char == ',') 3732fe6060f1SDimitry Andric return SendIllFormedResponse(packet, "Missing address in QMemTags packet"); 3733fe6060f1SDimitry Andric const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0); 3734fe6060f1SDimitry Andric 3735fe6060f1SDimitry Andric // Length 3736fe6060f1SDimitry Andric char previous_char = packet.GetChar(); 3737fe6060f1SDimitry Andric current_char = packet.Peek(); 3738fe6060f1SDimitry Andric // If we don't have a separator or the length field is empty 3739fe6060f1SDimitry Andric if (previous_char != ',' || (current_char && *current_char == ':')) 3740fe6060f1SDimitry Andric return SendIllFormedResponse(packet, 3741fe6060f1SDimitry Andric "Invalid addr,length pair in QMemTags packet"); 3742fe6060f1SDimitry Andric 3743fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1) 3744fe6060f1SDimitry Andric return SendIllFormedResponse( 3745fe6060f1SDimitry Andric packet, "Too short QMemtags: packet (looking for length)"); 3746fe6060f1SDimitry Andric const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0); 3747fe6060f1SDimitry Andric 3748fe6060f1SDimitry Andric // Type 3749fe6060f1SDimitry Andric const char *invalid_type_err = "Invalid type field in QMemTags: packet"; 3750fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') 3751fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 3752fe6060f1SDimitry Andric 3753fe6060f1SDimitry Andric // Our GetU64 uses strtoull which allows leading +/-, we don't want that. 3754fe6060f1SDimitry Andric const char *first_type_char = packet.Peek(); 3755fe6060f1SDimitry Andric if (first_type_char && (*first_type_char == '+' || *first_type_char == '-')) 3756fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 3757fe6060f1SDimitry Andric 3758fe6060f1SDimitry Andric // The type is a signed integer but is in the packet as its raw bytes. 3759fe6060f1SDimitry Andric // So parse first as unsigned then cast to signed later. 3760fe6060f1SDimitry Andric // We extract to 64 bit, even though we only expect 32, so that we've 3761fe6060f1SDimitry Andric // got some invalid value we can check for. 3762fe6060f1SDimitry Andric uint64_t raw_type = 3763fe6060f1SDimitry Andric packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16); 3764fe6060f1SDimitry Andric if (raw_type > std::numeric_limits<uint32_t>::max()) 3765fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_type_err); 37666e75b2fbSDimitry Andric 37676e75b2fbSDimitry Andric // First narrow to 32 bits. Otherwise the copy below would get the wrong 37686e75b2fbSDimitry Andric // 4 bytes on big endian. 37696e75b2fbSDimitry Andric uint32_t raw_type_32 = raw_type; 37706e75b2fbSDimitry Andric int32_t type = reinterpret_cast<int32_t &>(raw_type_32); 3771fe6060f1SDimitry Andric 3772fe6060f1SDimitry Andric // Tag data 3773fe6060f1SDimitry Andric if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':') 3774fe6060f1SDimitry Andric return SendIllFormedResponse(packet, 3775fe6060f1SDimitry Andric "Missing tag data in QMemTags: packet"); 3776fe6060f1SDimitry Andric 3777fe6060f1SDimitry Andric // Must be 2 chars per byte 3778fe6060f1SDimitry Andric const char *invalid_data_err = "Invalid tag data in QMemTags: packet"; 3779fe6060f1SDimitry Andric if (packet.GetBytesLeft() % 2) 3780fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_data_err); 3781fe6060f1SDimitry Andric 3782fe6060f1SDimitry Andric // This is bytes here and is unpacked into target specific tags later 3783fe6060f1SDimitry Andric // We cannot assume that number of bytes == length here because the server 3784fe6060f1SDimitry Andric // can repeat tags to fill a given range. 3785fe6060f1SDimitry Andric std::vector<uint8_t> tag_data; 3786fe6060f1SDimitry Andric // Zero length writes will not have any tag data 3787fe6060f1SDimitry Andric // (but we pass them on because it will still check that tagging is enabled) 3788fe6060f1SDimitry Andric if (packet.GetBytesLeft()) { 3789fe6060f1SDimitry Andric size_t byte_count = packet.GetBytesLeft() / 2; 3790fe6060f1SDimitry Andric tag_data.resize(byte_count); 3791fe6060f1SDimitry Andric size_t converted_bytes = packet.GetHexBytes(tag_data, 0); 3792fe6060f1SDimitry Andric if (converted_bytes != byte_count) { 3793fe6060f1SDimitry Andric return SendIllFormedResponse(packet, invalid_data_err); 3794fe6060f1SDimitry Andric } 3795fe6060f1SDimitry Andric } 3796fe6060f1SDimitry Andric 3797fe6060f1SDimitry Andric Status status = 3798fe6060f1SDimitry Andric m_current_process->WriteMemoryTags(type, addr, length, tag_data); 3799fe6060f1SDimitry Andric return status.Success() ? SendOKResponse() : SendErrorResponse(1); 3800fe6060f1SDimitry Andric } 3801fe6060f1SDimitry Andric 3802349cc55cSDimitry Andric GDBRemoteCommunication::PacketResult 3803349cc55cSDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_qSaveCore( 3804349cc55cSDimitry Andric StringExtractorGDBRemote &packet) { 3805349cc55cSDimitry Andric // Fail if we don't have a current process. 3806349cc55cSDimitry Andric if (!m_current_process || 3807349cc55cSDimitry Andric (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) 3808349cc55cSDimitry Andric return SendErrorResponse(Status("Process not running.")); 3809349cc55cSDimitry Andric 3810349cc55cSDimitry Andric std::string path_hint; 3811349cc55cSDimitry Andric 3812349cc55cSDimitry Andric StringRef packet_str{packet.GetStringRef()}; 3813349cc55cSDimitry Andric assert(packet_str.startswith("qSaveCore")); 3814349cc55cSDimitry Andric if (packet_str.consume_front("qSaveCore;")) { 3815349cc55cSDimitry Andric for (auto x : llvm::split(packet_str, ';')) { 3816349cc55cSDimitry Andric if (x.consume_front("path-hint:")) 3817349cc55cSDimitry Andric StringExtractor(x).GetHexByteString(path_hint); 3818349cc55cSDimitry Andric else 3819349cc55cSDimitry Andric return SendErrorResponse(Status("Unsupported qSaveCore option")); 3820349cc55cSDimitry Andric } 3821349cc55cSDimitry Andric } 3822349cc55cSDimitry Andric 3823349cc55cSDimitry Andric llvm::Expected<std::string> ret = m_current_process->SaveCore(path_hint); 3824349cc55cSDimitry Andric if (!ret) 3825349cc55cSDimitry Andric return SendErrorResponse(ret.takeError()); 3826349cc55cSDimitry Andric 3827349cc55cSDimitry Andric StreamString response; 3828349cc55cSDimitry Andric response.PutCString("core-path:"); 3829349cc55cSDimitry Andric response.PutStringAsRawHex8(ret.get()); 3830349cc55cSDimitry Andric return SendPacketNoLock(response.GetString()); 3831349cc55cSDimitry Andric } 3832349cc55cSDimitry Andric 383381ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 383481ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_QNonStop( 383581ad6265SDimitry Andric StringExtractorGDBRemote &packet) { 383681ad6265SDimitry Andric StringRef packet_str{packet.GetStringRef()}; 383781ad6265SDimitry Andric assert(packet_str.startswith("QNonStop:")); 383881ad6265SDimitry Andric packet_str.consume_front("QNonStop:"); 383981ad6265SDimitry Andric if (packet_str == "0") { 384081ad6265SDimitry Andric m_non_stop = false; 384181ad6265SDimitry Andric // TODO: stop all threads 384281ad6265SDimitry Andric } else if (packet_str == "1") { 384381ad6265SDimitry Andric m_non_stop = true; 384481ad6265SDimitry Andric } else 384581ad6265SDimitry Andric return SendErrorResponse(Status("Invalid QNonStop packet")); 384681ad6265SDimitry Andric return SendOKResponse(); 384781ad6265SDimitry Andric } 384881ad6265SDimitry Andric 384981ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 385081ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vStopped( 385181ad6265SDimitry Andric StringExtractorGDBRemote &packet) { 385281ad6265SDimitry Andric // Per the protocol, the first message put into the queue is sent 385381ad6265SDimitry Andric // immediately. However, it remains the queue until the client ACKs 385481ad6265SDimitry Andric // it via vStopped -- then we pop it and send the next message. 385581ad6265SDimitry Andric // The process repeats until the last message in the queue is ACK-ed, 385681ad6265SDimitry Andric // in which case the vStopped packet sends an OK response. 385781ad6265SDimitry Andric 385881ad6265SDimitry Andric if (m_stop_notification_queue.empty()) 385981ad6265SDimitry Andric return SendErrorResponse(Status("No pending notification to ack")); 386081ad6265SDimitry Andric m_stop_notification_queue.pop_front(); 386181ad6265SDimitry Andric if (!m_stop_notification_queue.empty()) 386281ad6265SDimitry Andric return SendPacketNoLock(m_stop_notification_queue.front()); 386381ad6265SDimitry Andric // If this was the last notification and all the processes exited, 386481ad6265SDimitry Andric // terminate the server. 386581ad6265SDimitry Andric if (m_debugged_processes.empty()) { 386681ad6265SDimitry Andric m_exit_now = true; 386781ad6265SDimitry Andric m_mainloop.RequestTermination(); 386881ad6265SDimitry Andric } 386981ad6265SDimitry Andric return SendOKResponse(); 387081ad6265SDimitry Andric } 387181ad6265SDimitry Andric 387281ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 387381ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_vCtrlC( 387481ad6265SDimitry Andric StringExtractorGDBRemote &packet) { 387581ad6265SDimitry Andric if (!m_non_stop) 387681ad6265SDimitry Andric return SendErrorResponse(Status("vCtrl is only valid in non-stop mode")); 387781ad6265SDimitry Andric 387881ad6265SDimitry Andric PacketResult interrupt_res = Handle_interrupt(packet); 387981ad6265SDimitry Andric // If interrupting the process failed, pass the result through. 388081ad6265SDimitry Andric if (interrupt_res != PacketResult::Success) 388181ad6265SDimitry Andric return interrupt_res; 388281ad6265SDimitry Andric // Otherwise, vCtrlC should issue an OK response (normal interrupts do not). 388381ad6265SDimitry Andric return SendOKResponse(); 388481ad6265SDimitry Andric } 388581ad6265SDimitry Andric 388681ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 388781ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::Handle_T(StringExtractorGDBRemote &packet) { 388881ad6265SDimitry Andric packet.SetFilePos(strlen("T")); 388981ad6265SDimitry Andric auto pid_tid = packet.GetPidTid(m_current_process ? m_current_process->GetID() 389081ad6265SDimitry Andric : LLDB_INVALID_PROCESS_ID); 389181ad6265SDimitry Andric if (!pid_tid) 389281ad6265SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 389381ad6265SDimitry Andric inconvertibleErrorCode(), "Malformed thread-id")); 389481ad6265SDimitry Andric 389581ad6265SDimitry Andric lldb::pid_t pid = pid_tid->first; 389681ad6265SDimitry Andric lldb::tid_t tid = pid_tid->second; 389781ad6265SDimitry Andric 389881ad6265SDimitry Andric // Technically, this would also be caught by the PID check but let's be more 389981ad6265SDimitry Andric // explicit about the error. 390081ad6265SDimitry Andric if (pid == LLDB_INVALID_PROCESS_ID) 390181ad6265SDimitry Andric return SendErrorResponse(llvm::make_error<StringError>( 390281ad6265SDimitry Andric inconvertibleErrorCode(), "No current process and no PID provided")); 390381ad6265SDimitry Andric 390481ad6265SDimitry Andric // Check the process ID and find respective process instance. 390581ad6265SDimitry Andric auto new_process_it = m_debugged_processes.find(pid); 390681ad6265SDimitry Andric if (new_process_it == m_debugged_processes.end()) 390781ad6265SDimitry Andric return SendErrorResponse(1); 390881ad6265SDimitry Andric 390981ad6265SDimitry Andric // Check the thread ID 391081ad6265SDimitry Andric if (!new_process_it->second->GetThreadByID(tid)) 391181ad6265SDimitry Andric return SendErrorResponse(2); 391281ad6265SDimitry Andric 391381ad6265SDimitry Andric return SendOKResponse(); 391481ad6265SDimitry Andric } 391581ad6265SDimitry Andric 39160b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { 391781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 39180b57cec5SDimitry Andric 39190b57cec5SDimitry Andric // Tell the stdio connection to shut down. 39200b57cec5SDimitry Andric if (m_stdio_communication.IsConnected()) { 39210b57cec5SDimitry Andric auto connection = m_stdio_communication.GetConnection(); 39220b57cec5SDimitry Andric if (connection) { 39230b57cec5SDimitry Andric Status error; 39240b57cec5SDimitry Andric connection->Disconnect(&error); 39250b57cec5SDimitry Andric 39260b57cec5SDimitry Andric if (error.Success()) { 39279dba64beSDimitry Andric LLDB_LOGF(log, 39289dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s disconnect process " 39290b57cec5SDimitry Andric "terminal stdio - SUCCESS", 39300b57cec5SDimitry Andric __FUNCTION__); 39310b57cec5SDimitry Andric } else { 39329dba64beSDimitry Andric LLDB_LOGF(log, 39339dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s disconnect process " 39340b57cec5SDimitry Andric "terminal stdio - FAIL: %s", 39350b57cec5SDimitry Andric __FUNCTION__, error.AsCString()); 39360b57cec5SDimitry Andric } 39370b57cec5SDimitry Andric } 39380b57cec5SDimitry Andric } 39390b57cec5SDimitry Andric } 39400b57cec5SDimitry Andric 39410b57cec5SDimitry Andric NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( 39420b57cec5SDimitry Andric StringExtractorGDBRemote &packet) { 39430b57cec5SDimitry Andric // We have no thread if we don't have a process. 3944fe6060f1SDimitry Andric if (!m_current_process || 3945fe6060f1SDimitry Andric m_current_process->GetID() == LLDB_INVALID_PROCESS_ID) 39460b57cec5SDimitry Andric return nullptr; 39470b57cec5SDimitry Andric 39480b57cec5SDimitry Andric // If the client hasn't asked for thread suffix support, there will not be a 39490b57cec5SDimitry Andric // thread suffix. Use the current thread in that case. 39500b57cec5SDimitry Andric if (!m_thread_suffix_supported) { 39510b57cec5SDimitry Andric const lldb::tid_t current_tid = GetCurrentThreadID(); 39520b57cec5SDimitry Andric if (current_tid == LLDB_INVALID_THREAD_ID) 39530b57cec5SDimitry Andric return nullptr; 39540b57cec5SDimitry Andric else if (current_tid == 0) { 39550b57cec5SDimitry Andric // Pick a thread. 3956fe6060f1SDimitry Andric return m_current_process->GetThreadAtIndex(0); 39570b57cec5SDimitry Andric } else 3958fe6060f1SDimitry Andric return m_current_process->GetThreadByID(current_tid); 39590b57cec5SDimitry Andric } 39600b57cec5SDimitry Andric 396181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Thread); 39620b57cec5SDimitry Andric 39630b57cec5SDimitry Andric // Parse out the ';'. 39640b57cec5SDimitry Andric if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') { 39659dba64beSDimitry Andric LLDB_LOGF(log, 39669dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " 39670b57cec5SDimitry Andric "error: expected ';' prior to start of thread suffix: packet " 39680b57cec5SDimitry Andric "contents = '%s'", 39699dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 39700b57cec5SDimitry Andric return nullptr; 39710b57cec5SDimitry Andric } 39720b57cec5SDimitry Andric 39730b57cec5SDimitry Andric if (!packet.GetBytesLeft()) 39740b57cec5SDimitry Andric return nullptr; 39750b57cec5SDimitry Andric 39760b57cec5SDimitry Andric // Parse out thread: portion. 39770b57cec5SDimitry Andric if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) { 39789dba64beSDimitry Andric LLDB_LOGF(log, 39799dba64beSDimitry Andric "GDBRemoteCommunicationServerLLGS::%s gdb-remote parse " 39800b57cec5SDimitry Andric "error: expected 'thread:' but not found, packet contents = " 39810b57cec5SDimitry Andric "'%s'", 39829dba64beSDimitry Andric __FUNCTION__, packet.GetStringRef().data()); 39830b57cec5SDimitry Andric return nullptr; 39840b57cec5SDimitry Andric } 39850b57cec5SDimitry Andric packet.SetFilePos(packet.GetFilePos() + strlen("thread:")); 39860b57cec5SDimitry Andric const lldb::tid_t tid = packet.GetHexMaxU64(false, 0); 39870b57cec5SDimitry Andric if (tid != 0) 3988fe6060f1SDimitry Andric return m_current_process->GetThreadByID(tid); 39890b57cec5SDimitry Andric 39900b57cec5SDimitry Andric return nullptr; 39910b57cec5SDimitry Andric } 39920b57cec5SDimitry Andric 39930b57cec5SDimitry Andric lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const { 39940b57cec5SDimitry Andric if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) { 39950b57cec5SDimitry Andric // Use whatever the debug process says is the current thread id since the 39960b57cec5SDimitry Andric // protocol either didn't specify or specified we want any/all threads 39970b57cec5SDimitry Andric // marked as the current thread. 3998fe6060f1SDimitry Andric if (!m_current_process) 39990b57cec5SDimitry Andric return LLDB_INVALID_THREAD_ID; 4000fe6060f1SDimitry Andric return m_current_process->GetCurrentThreadID(); 40010b57cec5SDimitry Andric } 40020b57cec5SDimitry Andric // Use the specific current thread id set by the gdb remote protocol. 40030b57cec5SDimitry Andric return m_current_tid; 40040b57cec5SDimitry Andric } 40050b57cec5SDimitry Andric 40060b57cec5SDimitry Andric uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() { 40070b57cec5SDimitry Andric std::lock_guard<std::mutex> guard(m_saved_registers_mutex); 40080b57cec5SDimitry Andric return m_next_saved_registers_id++; 40090b57cec5SDimitry Andric } 40100b57cec5SDimitry Andric 40110b57cec5SDimitry Andric void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() { 401281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Process); 40130b57cec5SDimitry Andric 40140b57cec5SDimitry Andric LLDB_LOG(log, "clearing {0} xfer buffers", m_xfer_buffer_map.size()); 40150b57cec5SDimitry Andric m_xfer_buffer_map.clear(); 40160b57cec5SDimitry Andric } 40170b57cec5SDimitry Andric 40180b57cec5SDimitry Andric FileSpec 40190b57cec5SDimitry Andric GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path, 40200b57cec5SDimitry Andric const ArchSpec &arch) { 4021fe6060f1SDimitry Andric if (m_current_process) { 40220b57cec5SDimitry Andric FileSpec file_spec; 4023fe6060f1SDimitry Andric if (m_current_process 40240b57cec5SDimitry Andric ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec) 40250b57cec5SDimitry Andric .Success()) { 40260b57cec5SDimitry Andric if (FileSystem::Instance().Exists(file_spec)) 40270b57cec5SDimitry Andric return file_spec; 40280b57cec5SDimitry Andric } 40290b57cec5SDimitry Andric } 40300b57cec5SDimitry Andric 40310b57cec5SDimitry Andric return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch); 40320b57cec5SDimitry Andric } 40339dba64beSDimitry Andric 40349dba64beSDimitry Andric std::string GDBRemoteCommunicationServerLLGS::XMLEncodeAttributeValue( 40359dba64beSDimitry Andric llvm::StringRef value) { 40369dba64beSDimitry Andric std::string result; 40379dba64beSDimitry Andric for (const char &c : value) { 40389dba64beSDimitry Andric switch (c) { 40399dba64beSDimitry Andric case '\'': 40409dba64beSDimitry Andric result += "'"; 40419dba64beSDimitry Andric break; 40429dba64beSDimitry Andric case '"': 40439dba64beSDimitry Andric result += """; 40449dba64beSDimitry Andric break; 40459dba64beSDimitry Andric case '<': 40469dba64beSDimitry Andric result += "<"; 40479dba64beSDimitry Andric break; 40489dba64beSDimitry Andric case '>': 40499dba64beSDimitry Andric result += ">"; 40509dba64beSDimitry Andric break; 40519dba64beSDimitry Andric default: 40529dba64beSDimitry Andric result += c; 40539dba64beSDimitry Andric break; 40549dba64beSDimitry Andric } 40559dba64beSDimitry Andric } 40569dba64beSDimitry Andric return result; 40579dba64beSDimitry Andric } 4058fe6060f1SDimitry Andric 4059fe6060f1SDimitry Andric std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures( 4060fe6060f1SDimitry Andric const llvm::ArrayRef<llvm::StringRef> client_features) { 4061fe6060f1SDimitry Andric std::vector<std::string> ret = 4062fe6060f1SDimitry Andric GDBRemoteCommunicationServerCommon::HandleFeatures(client_features); 4063fe6060f1SDimitry Andric ret.insert(ret.end(), { 4064fe6060f1SDimitry Andric "QThreadSuffixSupported+", 4065fe6060f1SDimitry Andric "QListThreadsInStopReply+", 4066fe6060f1SDimitry Andric "qXfer:features:read+", 406781ad6265SDimitry Andric "QNonStop+", 4068fe6060f1SDimitry Andric }); 4069fe6060f1SDimitry Andric 4070fe6060f1SDimitry Andric // report server-only features 4071fe6060f1SDimitry Andric using Extension = NativeProcessProtocol::Extension; 4072fe6060f1SDimitry Andric Extension plugin_features = m_process_factory.GetSupportedExtensions(); 4073fe6060f1SDimitry Andric if (bool(plugin_features & Extension::pass_signals)) 4074fe6060f1SDimitry Andric ret.push_back("QPassSignals+"); 4075fe6060f1SDimitry Andric if (bool(plugin_features & Extension::auxv)) 4076fe6060f1SDimitry Andric ret.push_back("qXfer:auxv:read+"); 4077fe6060f1SDimitry Andric if (bool(plugin_features & Extension::libraries_svr4)) 4078fe6060f1SDimitry Andric ret.push_back("qXfer:libraries-svr4:read+"); 407904eeddc0SDimitry Andric if (bool(plugin_features & Extension::siginfo_read)) 408004eeddc0SDimitry Andric ret.push_back("qXfer:siginfo:read+"); 4081fe6060f1SDimitry Andric if (bool(plugin_features & Extension::memory_tagging)) 4082fe6060f1SDimitry Andric ret.push_back("memory-tagging+"); 4083349cc55cSDimitry Andric if (bool(plugin_features & Extension::savecore)) 4084349cc55cSDimitry Andric ret.push_back("qSaveCore+"); 4085fe6060f1SDimitry Andric 4086fe6060f1SDimitry Andric // check for client features 4087fe6060f1SDimitry Andric m_extensions_supported = {}; 4088fe6060f1SDimitry Andric for (llvm::StringRef x : client_features) 4089fe6060f1SDimitry Andric m_extensions_supported |= 4090fe6060f1SDimitry Andric llvm::StringSwitch<Extension>(x) 4091fe6060f1SDimitry Andric .Case("multiprocess+", Extension::multiprocess) 4092fe6060f1SDimitry Andric .Case("fork-events+", Extension::fork) 4093fe6060f1SDimitry Andric .Case("vfork-events+", Extension::vfork) 4094fe6060f1SDimitry Andric .Default({}); 4095fe6060f1SDimitry Andric 4096fe6060f1SDimitry Andric m_extensions_supported &= plugin_features; 4097fe6060f1SDimitry Andric 4098fe6060f1SDimitry Andric // fork & vfork require multiprocess 4099fe6060f1SDimitry Andric if (!bool(m_extensions_supported & Extension::multiprocess)) 4100fe6060f1SDimitry Andric m_extensions_supported &= ~(Extension::fork | Extension::vfork); 4101fe6060f1SDimitry Andric 4102fe6060f1SDimitry Andric // report only if actually supported 4103fe6060f1SDimitry Andric if (bool(m_extensions_supported & Extension::multiprocess)) 4104fe6060f1SDimitry Andric ret.push_back("multiprocess+"); 4105fe6060f1SDimitry Andric if (bool(m_extensions_supported & Extension::fork)) 4106fe6060f1SDimitry Andric ret.push_back("fork-events+"); 4107fe6060f1SDimitry Andric if (bool(m_extensions_supported & Extension::vfork)) 4108fe6060f1SDimitry Andric ret.push_back("vfork-events+"); 4109fe6060f1SDimitry Andric 4110fe6060f1SDimitry Andric for (auto &x : m_debugged_processes) 4111fe6060f1SDimitry Andric SetEnabledExtensions(*x.second); 4112fe6060f1SDimitry Andric return ret; 4113fe6060f1SDimitry Andric } 4114fe6060f1SDimitry Andric 4115fe6060f1SDimitry Andric void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions( 4116fe6060f1SDimitry Andric NativeProcessProtocol &process) { 4117fe6060f1SDimitry Andric NativeProcessProtocol::Extension flags = m_extensions_supported; 4118fe6060f1SDimitry Andric assert(!bool(flags & ~m_process_factory.GetSupportedExtensions())); 4119fe6060f1SDimitry Andric process.SetEnabledExtensions(flags); 4120fe6060f1SDimitry Andric } 4121349cc55cSDimitry Andric 412281ad6265SDimitry Andric GDBRemoteCommunication::PacketResult 412381ad6265SDimitry Andric GDBRemoteCommunicationServerLLGS::SendContinueSuccessResponse() { 412481ad6265SDimitry Andric // TODO: how to handle forwarding in non-stop mode? 412581ad6265SDimitry Andric StartSTDIOForwarding(); 412681ad6265SDimitry Andric return m_non_stop ? SendOKResponse() : PacketResult::Success; 412781ad6265SDimitry Andric } 412881ad6265SDimitry Andric 412981ad6265SDimitry Andric void GDBRemoteCommunicationServerLLGS::AppendThreadIDToResponse( 413081ad6265SDimitry Andric Stream &response, lldb::pid_t pid, lldb::tid_t tid) { 413181ad6265SDimitry Andric if (bool(m_extensions_supported & 413281ad6265SDimitry Andric NativeProcessProtocol::Extension::multiprocess)) 413381ad6265SDimitry Andric response.Format("p{0:x-}.", pid); 413481ad6265SDimitry Andric response.Format("{0:x-}", tid); 413581ad6265SDimitry Andric } 413681ad6265SDimitry Andric 4137349cc55cSDimitry Andric std::string 4138349cc55cSDimitry Andric lldb_private::process_gdb_remote::LLGSArgToURL(llvm::StringRef url_arg, 4139349cc55cSDimitry Andric bool reverse_connect) { 4140349cc55cSDimitry Andric // Try parsing the argument as URL. 4141349cc55cSDimitry Andric if (llvm::Optional<URI> url = URI::Parse(url_arg)) { 4142349cc55cSDimitry Andric if (reverse_connect) 4143349cc55cSDimitry Andric return url_arg.str(); 4144349cc55cSDimitry Andric 4145349cc55cSDimitry Andric // Translate the scheme from LLGS notation to ConnectionFileDescriptor. 4146349cc55cSDimitry Andric // If the scheme doesn't match any, pass it through to support using CFD 4147349cc55cSDimitry Andric // schemes directly. 4148349cc55cSDimitry Andric std::string new_url = llvm::StringSwitch<std::string>(url->scheme) 4149349cc55cSDimitry Andric .Case("tcp", "listen") 4150349cc55cSDimitry Andric .Case("unix", "unix-accept") 4151349cc55cSDimitry Andric .Case("unix-abstract", "unix-abstract-accept") 4152349cc55cSDimitry Andric .Default(url->scheme.str()); 4153349cc55cSDimitry Andric llvm::append_range(new_url, url_arg.substr(url->scheme.size())); 4154349cc55cSDimitry Andric return new_url; 4155349cc55cSDimitry Andric } 4156349cc55cSDimitry Andric 4157349cc55cSDimitry Andric std::string host_port = url_arg.str(); 4158349cc55cSDimitry Andric // If host_and_port starts with ':', default the host to be "localhost" and 4159349cc55cSDimitry Andric // expect the remainder to be the port. 4160349cc55cSDimitry Andric if (url_arg.startswith(":")) 4161349cc55cSDimitry Andric host_port.insert(0, "localhost"); 4162349cc55cSDimitry Andric 4163349cc55cSDimitry Andric // Try parsing the (preprocessed) argument as host:port pair. 4164349cc55cSDimitry Andric if (!llvm::errorToBool(Socket::DecodeHostAndPort(host_port).takeError())) 4165349cc55cSDimitry Andric return (reverse_connect ? "connect://" : "listen://") + host_port; 4166349cc55cSDimitry Andric 4167349cc55cSDimitry Andric // If none of the above applied, interpret the argument as UNIX socket path. 4168349cc55cSDimitry Andric return (reverse_connect ? "unix-connect://" : "unix-accept://") + 4169349cc55cSDimitry Andric url_arg.str(); 4170349cc55cSDimitry Andric } 4171