brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.5 KiB · b32c00a Raw
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