437 lines · c
1 2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Created by Greg Clayton on 12/12/07.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBREMOTE_H14#define LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBREMOTE_H15 16#include "DNB.h"17#include "RNBContext.h"18#include "RNBDefs.h"19#include "RNBSocket.h"20#include <deque>21#include <map>22#include <string>23#include <vector>24 25class RNBSocket;26class RNBContext;27 28enum event_loop_mode { debug_nub, gdb_remote_protocol, done };29 30enum class compression_types { zlib_deflate, lz4, lzma, lzfse, none };31 32class RNBRemote {33public:34 // clang-format off35 enum PacketEnum {36 invalid_packet = 0,37 ack, // '+'38 nack, // '-'39 halt, // ^C (async halt)40 use_extended_mode, // '!'41 why_halted, // '?'42 set_argv, // 'A'43 set_bp, // 'B'44 cont, // 'c'45 continue_with_sig, // 'C'46 detach, // 'D'47 set_thread, // 'H'48 step_inferior_one_cycle, // 'i'49 signal_and_step_inf_one_cycle, // 'I'50 kill, // 'k'51 read_memory, // 'm'52 write_memory, // 'M'53 read_register, // 'p'54 write_register, // 'P'55 restart, // 'R'56 single_step, // 's'57 single_step_with_sig, // 'S'58 search_mem_backwards, // 't'59 thread_alive_p, // 'T'60 vattach, // 'vAttach;pid'61 vattachwait, // 'vAttachWait:XX...' where XX is one or more hex encoded62 // process name ASCII bytes63 vattachorwait, // 'vAttachOrWait:XX...' where XX is one or more hex encoded64 // process name ASCII bytes65 vattachname, // 'vAttachName:XX...' where XX is one or more hex encoded66 // process name ASCII bytes67 vcont, // 'vCont'68 vcont_list_actions, // 'vCont?'69 read_data_from_memory, // 'x'70 write_data_to_memory, // 'X'71 insert_mem_bp, // 'Z0'72 remove_mem_bp, // 'z0'73 insert_hardware_bp, // 'Z1'74 remove_hardware_bp, // 'z1'75 insert_write_watch_bp, // 'Z2'76 remove_write_watch_bp, // 'z2'77 insert_read_watch_bp, // 'Z3'78 remove_read_watch_bp, // 'z3'79 insert_access_watch_bp, // 'Z4'80 remove_access_watch_bp, // 'z4'81 82 query_monitor, // 'qRcmd'83 query_current_thread_id, // 'qC'84 query_get_pid, // 'qGetPid'85 query_echo, // 'qEcho'86 query_thread_ids_first, // 'qfThreadInfo'87 query_thread_ids_subsequent, // 'qsThreadInfo'88 query_thread_extra_info, // 'qThreadExtraInfo'89 query_thread_stop_info, // 'qThreadStopInfo'90 query_image_offsets, // 'qOffsets'91 query_symbol_lookup, // 'qSymbol'92 query_launch_success, // 'qLaunchSuccess'93 query_register_info, // 'qRegisterInfo'94 query_shlib_notify_info_addr, // 'qShlibInfoAddr'95 query_step_packet_supported, // 'qStepPacketSupported'96 query_supported_features, // 'qSupported'97 query_vattachorwait_supported, // 'qVAttachOrWaitSupported'98 query_sync_thread_state_supported, // 'QSyncThreadState'99 query_host_info, // 'qHostInfo'100 query_gdb_server_version, // 'qGDBServerVersion'101 query_process_info, // 'qProcessInfo'102 json_query_thread_extended_info, // 'jThreadExtendedInfo'103 json_query_get_loaded_dynamic_libraries_infos, // 'jGetLoadedDynamicLibrariesInfos'104 json_query_threads_info, // 'jThreadsInfo'105 json_query_get_shared_cache_info, // 'jGetSharedCacheInfo'106 pass_signals_to_inferior, // 'QPassSignals'107 start_noack_mode, // 'QStartNoAckMode'108 prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID109 set_logging_mode, // 'QSetLogging:'110 set_ignored_exceptions, // 'QSetIgnoredExceptions' 111 set_max_packet_size, // 'QSetMaxPacketSize:'112 set_max_payload_size, // 'QSetMaxPayloadSize:'113 set_environment_variable, // 'QEnvironment:'114 set_environment_variable_hex, // 'QEnvironmentHexEncoded:'115 set_launch_arch, // 'QLaunchArch:'116 set_disable_aslr, // 'QSetDisableASLR:'117 set_stdin, // 'QSetSTDIN:'118 set_stdout, // 'QSetSTDOUT:'119 set_stderr, // 'QSetSTDERR:'120 set_working_dir, // 'QSetWorkingDir:'121 set_list_threads_in_stop_reply, // 'QListThreadsInStopReply:'122 sync_thread_state, // 'QSyncThreadState:'123 memory_region_info, // 'qMemoryRegionInfo:'124 get_memory_tags, // 'qMemTags:'125 get_profile_data, // 'qGetProfileData'126 set_enable_profiling, // 'QSetEnableAsyncProfiling'127 enable_compression, // 'QEnableCompression:'128 watchpoint_support_info, // 'qWatchpointSupportInfo:'129 allocate_memory, // '_M'130 deallocate_memory, // '_m'131 set_process_event, // 'QSetProcessEvent:'132 save_register_state, // '_g'133 restore_register_state, // '_G'134 speed_test, // 'qSpeedTest:'135 set_detach_on_error, // 'QSetDetachOnError:'136 query_transfer, // 'qXfer:'137 json_query_dyld_process_state, // 'jGetDyldProcessState'138 enable_error_strings, // 'QEnableErrorStrings'139 multi_mem_read, // 'MultiMemRead'140 unknown_type141 };142 // clang-format on143 144 typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p);145 146 RNBRemote();147 ~RNBRemote();148 149 void Initialize();150 151 bool InitializeRegisters(bool force = false);152 153 rnb_err_t HandleAsyncPacket(PacketEnum *type = NULL);154 rnb_err_t HandleReceivedPacket(PacketEnum *type = NULL);155 156 nub_thread_t GetContinueThread() const { return m_continue_thread; }157 158 void SetContinueThread(nub_thread_t tid) { m_continue_thread = tid; }159 160 nub_thread_t GetCurrentThread() const {161 if (m_thread == 0 || m_thread == (nub_thread_t)-1)162 return DNBProcessGetCurrentThread(m_ctx.ProcessID());163 return m_thread;164 }165 166 void SetCurrentThread(nub_thread_t tid) {167 DNBProcessSetCurrentThread(m_ctx.ProcessID(), tid);168 m_thread = tid;169 }170 171 static void *ThreadFunctionReadRemoteData(void *arg);172 void StartReadRemoteDataThread();173 void StopReadRemoteDataThread();174 175 void NotifyThatProcessStopped(void);176 177 rnb_err_t HandlePacket_A(const char *p);178 rnb_err_t HandlePacket_H(const char *p);179 rnb_err_t HandlePacket_qC(const char *p);180 rnb_err_t HandlePacket_qRcmd(const char *p);181 rnb_err_t HandlePacket_qGetPid(const char *p);182 rnb_err_t HandlePacket_qEcho(const char *p);183 rnb_err_t HandlePacket_qLaunchSuccess(const char *p);184 rnb_err_t HandlePacket_qRegisterInfo(const char *p);185 rnb_err_t HandlePacket_qShlibInfoAddr(const char *p);186 rnb_err_t HandlePacket_qStepPacketSupported(const char *p);187 rnb_err_t HandlePacket_qVAttachOrWaitSupported(const char *p);188 rnb_err_t HandlePacket_qSyncThreadStateSupported(const char *p);189 rnb_err_t HandlePacket_qThreadInfo(const char *p);190 rnb_err_t HandlePacket_jThreadExtendedInfo(const char *p);191 rnb_err_t HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p);192 rnb_err_t HandlePacket_jThreadsInfo(const char *p);193 rnb_err_t HandlePacket_jGetSharedCacheInfo(const char *p);194 rnb_err_t HandlePacket_qThreadExtraInfo(const char *p);195 rnb_err_t HandlePacket_qThreadStopInfo(const char *p);196 rnb_err_t HandlePacket_qHostInfo(const char *p);197 rnb_err_t HandlePacket_qGDBServerVersion(const char *p);198 rnb_err_t HandlePacket_qProcessInfo(const char *p);199 rnb_err_t HandlePacket_qSymbol(const char *p);200 rnb_err_t HandlePacket_QEnableErrorStrings(const char *p);201 rnb_err_t HandlePacket_QStartNoAckMode(const char *p);202 rnb_err_t HandlePacket_QThreadSuffixSupported(const char *p);203 rnb_err_t HandlePacket_QSetLogging(const char *p);204 rnb_err_t HandlePacket_QSetIgnoredExceptions(const char *p);205 rnb_err_t HandlePacket_QSetDisableASLR(const char *p);206 rnb_err_t HandlePacket_QSetSTDIO(const char *p);207 rnb_err_t HandlePacket_QSetWorkingDir(const char *p);208 rnb_err_t HandlePacket_QSetMaxPayloadSize(const char *p);209 rnb_err_t HandlePacket_QSetMaxPacketSize(const char *p);210 rnb_err_t HandlePacket_QEnvironment(const char *p);211 rnb_err_t HandlePacket_QEnvironmentHexEncoded(const char *p);212 rnb_err_t HandlePacket_QLaunchArch(const char *p);213 rnb_err_t HandlePacket_QListThreadsInStopReply(const char *p);214 rnb_err_t HandlePacket_QSyncThreadState(const char *p);215 rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID(const char *p);216 rnb_err_t HandlePacket_QSetProcessEvent(const char *p);217 rnb_err_t HandlePacket_last_signal(const char *p);218 rnb_err_t HandlePacket_m(const char *p);219 rnb_err_t HandlePacket_M(const char *p);220 rnb_err_t HandlePacket_MultiMemRead(const char *p);221 rnb_err_t HandlePacket_x(const char *p);222 rnb_err_t HandlePacket_X(const char *p);223 rnb_err_t HandlePacket_z(const char *p);224 rnb_err_t HandlePacket_T(const char *p);225 rnb_err_t HandlePacket_p(const char *p);226 rnb_err_t HandlePacket_P(const char *p);227 rnb_err_t HandlePacket_c(const char *p);228 rnb_err_t HandlePacket_C(const char *p);229 rnb_err_t HandlePacket_D(const char *p);230 rnb_err_t HandlePacket_k(const char *p);231 rnb_err_t HandlePacket_s(const char *p);232 rnb_err_t HandlePacket_S(const char *p);233 rnb_err_t HandlePacket_qSupported(const char *p);234 rnb_err_t HandlePacket_v(const char *p);235 rnb_err_t HandlePacket_UNIMPLEMENTED(const char *p);236 rnb_err_t HandlePacket_ILLFORMED(const char *file, int line, const char *p,237 const char *description);238 rnb_err_t HandlePacket_AllocateMemory(const char *p);239 rnb_err_t HandlePacket_DeallocateMemory(const char *p);240 rnb_err_t HandlePacket_SaveRegisterState(const char *p);241 rnb_err_t HandlePacket_RestoreRegisterState(const char *p);242 rnb_err_t HandlePacket_MemoryRegionInfo(const char *p);243 rnb_err_t HandlePacket_qMemTags(const char *p);244 rnb_err_t HandlePacket_GetProfileData(const char *p);245 rnb_err_t HandlePacket_SetEnableAsyncProfiling(const char *p);246 rnb_err_t HandlePacket_QEnableCompression(const char *p);247 rnb_err_t HandlePacket_WatchpointSupportInfo(const char *p);248 rnb_err_t HandlePacket_qSpeedTest(const char *p);249 rnb_err_t HandlePacket_qXfer(const char *p);250 rnb_err_t HandlePacket_stop_process(const char *p);251 rnb_err_t HandlePacket_QSetDetachOnError(const char *p);252 rnb_err_t HandlePacket_jGetDyldProcessState(const char *p);253 rnb_err_t SendStopReplyPacketForThread(nub_thread_t tid);254 rnb_err_t SendHexEncodedBytePacket(const char *header, const void *buf,255 size_t buf_len, const char *footer);256 rnb_err_t SendSTDOUTPacket(char *buf, nub_size_t buf_size);257 rnb_err_t SendSTDERRPacket(char *buf, nub_size_t buf_size);258 void FlushSTDIO();259 void SendAsyncProfileData();260 rnb_err_t SendAsyncProfileDataPacket(char *buf, nub_size_t buf_size);261 rnb_err_t SendAsyncJSONPacket(const JSONGenerator::Dictionary &dictionary);262 263 RNBContext &Context() { return m_ctx; }264 RNBSocket &Comm() { return m_comm; }265 266private:267 RNBRemote(const RNBRemote &) = delete;268 269protected:270 rnb_err_t GetCommData();271 void CommDataReceived(const std::string &data);272 struct Packet {273 typedef std::vector<Packet> collection;274 typedef collection::iterator iterator;275 typedef collection::const_iterator const_iterator;276 PacketEnum type;277 HandlePacketCallback normal; // Function to call when inferior is halted278 HandlePacketCallback async; // Function to call when inferior is running279 std::string abbrev;280 std::string printable_name;281 282 bool IsPlatformPacket() const {283 switch (type) {284 case set_logging_mode:285 case query_host_info:286 return true;287 default:288 break;289 }290 return false;291 }292 Packet()293 : type(invalid_packet), normal(NULL), async(NULL), abbrev(),294 printable_name() {}295 296 Packet(PacketEnum in_type, HandlePacketCallback in_normal,297 HandlePacketCallback in_async, const char *in_abbrev,298 const char *in_printable_name)299 : type(in_type), normal(in_normal), async(in_async), abbrev(in_abbrev),300 printable_name(in_printable_name) {}301 };302 303 struct DispatchQueueOffsets {304 uint16_t dqo_version;305 uint16_t dqo_label;306 uint16_t dqo_label_size;307 uint16_t dqo_flags;308 uint16_t dqo_flags_size;309 uint16_t dqo_serialnum;310 uint16_t dqo_serialnum_size;311 uint16_t dqo_width;312 uint16_t dqo_width_size;313 uint16_t dqo_running;314 uint16_t dqo_running_size;315 uint16_t dqo_suspend_cnt; // version 5 and later, starting with Mac OS X316 // 10.10/iOS 8317 uint16_t dqo_suspend_cnt_size; // version 5 and later, starting with Mac OS318 // X 10.10/iOS 8319 uint16_t dqo_target_queue; // version 5 and later, starting with Mac OS X320 // 10.10/iOS 8321 uint16_t dqo_target_queue_size; // version 5 and later, starting with Mac OS322 // X 10.10/iOS 8323 uint16_t324 dqo_priority; // version 5 and later, starting with Mac OS X 10.10/iOS 8325 uint16_t dqo_priority_size; // version 5 and later, starting with Mac OS X326 // 10.10/iOS 8327 328 DispatchQueueOffsets() { Clear(); }329 330 void Clear() {331 dqo_version = UINT16_MAX;332 dqo_label = UINT16_MAX;333 dqo_label_size = UINT16_MAX;334 dqo_flags = UINT16_MAX;335 dqo_flags_size = UINT16_MAX;336 dqo_serialnum = UINT16_MAX;337 dqo_serialnum_size = UINT16_MAX;338 dqo_width = UINT16_MAX;339 dqo_width_size = UINT16_MAX;340 dqo_running = UINT16_MAX;341 dqo_running_size = UINT16_MAX;342 dqo_suspend_cnt = UINT16_MAX;343 dqo_suspend_cnt_size = UINT16_MAX;344 dqo_target_queue = UINT16_MAX;345 dqo_target_queue_size = UINT16_MAX;346 dqo_priority = UINT16_MAX;347 dqo_priority_size = UINT16_MAX;348 }349 350 bool IsValid() const { return dqo_version != UINT16_MAX; }351 352 void GetThreadQueueInfo(nub_process_t pid, nub_addr_t dispatch_qaddr,353 nub_addr_t &dispatch_queue_t,354 std::string &queue_name, uint64_t &queue_width,355 uint64_t &queue_serialnum) const;356 };357 358 rnb_err_t GetPacket(std::string &packet_data, RNBRemote::Packet &packet_info,359 bool wait);360 rnb_err_t SendPacket(const std::string &);361 rnb_err_t SendErrorPacket(std::string errcode,362 const std::string &errmsg = "");363 std::string CompressString(const std::string &);364 365 void CreatePacketTable();366 rnb_err_t GetPacketPayload(std::string &);367 368 nub_thread_t ExtractThreadIDFromThreadSuffix(const char *p);369 370 void EnableCompressionNextSendPacket(compression_types);371 372 compression_types GetCompressionType();373 374 const DispatchQueueOffsets *GetDispatchQueueOffsets();375 376 JSONGenerator::ObjectSP377 GetJSONThreadsInfo(bool threads_with_valid_stop_info_only);378 379 RNBContext m_ctx; // process context380 RNBSocket m_comm; // communication port381 std::string m_arch;382 nub_thread_t m_continue_thread; // thread to continue; 0 for any, -1 for all383 nub_thread_t m_thread; // thread for other ops; 0 for any, -1 for all384 std::mutex m_mutex; // Mutex that protects385 DispatchQueueOffsets m_dispatch_queue_offsets;386 nub_addr_t m_dispatch_queue_offsets_addr;387 uint32_t m_qSymbol_index;388 uint32_t m_packets_recvd;389 Packet::collection m_packets;390 std::deque<std::string> m_rx_packets;391 std::string m_rx_partial_data; // For packets that may come in more than one392 // batch, anything left over can be left here393 pthread_t m_rx_pthread;394 uint32_t395 m_max_payload_size; // the maximum sized payload we should send to gdb396 bool m_extended_mode; // are we in extended mode?397 bool m_noack_mode; // are we in no-ack mode?398 bool m_thread_suffix_supported; // Set to true if the 'p', 'P', 'g', and 'G'399 // packets should be prefixed with the thread400 // ID and colon:401 // "$pRR;thread:TTTT;" instead of "$pRR"402 // "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV"403 // "$g;thread:TTTT" instead of "$g"404 // "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV"405 bool m_list_threads_in_stop_reply;406 407 size_t m_compression_minsize; // only packets larger than this size will be408 // compressed409 bool m_enable_compression_next_send_packet;410 411 compression_types m_compression_mode;412 413 bool m_enable_error_strings; // Whether we can append asciihex error strings414 // after Exx error replies415};416 417/* We translate the /usr/include/mach/exception_types.h exception types418 (e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses419 in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS). These hard420 coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb421 values in its include/gdb/signals.h. */422 423#define TARGET_EXC_BAD_ACCESS 0x91424#define TARGET_EXC_BAD_INSTRUCTION 0x92425#define TARGET_EXC_ARITHMETIC 0x93426#define TARGET_EXC_EMULATION 0x94427#define TARGET_EXC_SOFTWARE 0x95428#define TARGET_EXC_BREAKPOINT 0x96429 430/* Generally speaking, you can't assume gdb can receive more than 399 bytes431 at a time with a random gdb. This bufsize constant is only specifying432 how many bytes gdb can *receive* from debugserver -- it tells us nothing433 about how many bytes gdb might try to send in a single packet. */434#define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399435 436#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBREMOTE_H437