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