1 //===-- RNBRemote.h ---------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Created by Greg Clayton on 12/12/07. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef __RNBRemote_h__ 15 #define __RNBRemote_h__ 16 17 #include "RNBDefs.h" 18 #include "DNB.h" 19 #include "RNBContext.h" 20 #include "RNBSocket.h" 21 #include "PThreadMutex.h" 22 #include <string> 23 #include <vector> 24 #include <deque> 25 #include <map> 26 27 class RNBSocket; 28 class RNBContext; 29 class PThreadEvents; 30 31 enum event_loop_mode { debug_nub, gdb_remote_protocol, done }; 32 33 class RNBRemote 34 { 35 public: 36 37 typedef enum { 38 invalid_packet = 0, 39 ack, // '+' 40 nack, // '-' 41 halt, // ^C (async halt) 42 use_extended_mode, // '!' 43 why_halted, // '?' 44 set_argv, // 'A' 45 set_bp, // 'B' 46 cont, // 'c' 47 continue_with_sig, // 'C' 48 detach, // 'D' 49 read_general_regs, // 'g' 50 write_general_regs, // 'G' 51 set_thread, // 'H' 52 step_inferior_one_cycle, // 'i' 53 signal_and_step_inf_one_cycle, // 'I' 54 kill, // 'k' 55 read_memory, // 'm' 56 write_memory, // 'M' 57 read_register, // 'p' 58 write_register, // 'P' 59 restart, // 'R' 60 single_step, // 's' 61 single_step_with_sig, // 'S' 62 search_mem_backwards, // 't' 63 thread_alive_p, // 'T' 64 vattach, // 'vAttach;pid' 65 vattachwait, // 'vAttachWait:XX...' where XX is one or more hex encoded process name ASCII bytes 66 vattachorwait, // 'vAttachOrWait:XX...' where XX is one or more hex encoded process name ASCII bytes 67 vattachname, // 'vAttachName:XX...' where XX is one or more hex encoded process name ASCII bytes 68 vcont, // 'vCont' 69 vcont_list_actions, // 'vCont?' 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_thread_ids_first, // 'qfThreadInfo' 86 query_thread_ids_subsequent, // 'qsThreadInfo' 87 query_thread_extra_info, // 'qThreadExtraInfo' 88 query_thread_stop_info, // 'qThreadStopInfo' 89 query_image_offsets, // 'qOffsets' 90 query_symbol_lookup, // 'gSymbols' 91 query_launch_success, // 'qLaunchSuccess' 92 query_register_info, // 'qRegisterInfo' 93 query_shlib_notify_info_addr, // 'qShlibInfoAddr' 94 query_step_packet_supported, // 'qStepPacketSupported' 95 query_vattachorwait_supported, // 'qVAttachOrWaitSupported' 96 query_sync_thread_state_supported,// 'QSyncThreadState' 97 query_host_info, // 'qHostInfo' 98 query_gdb_server_version, // 'qGDBServerVersion' 99 query_process_info, // 'qProcessInfo' 100 pass_signals_to_inferior, // 'QPassSignals' 101 start_noack_mode, // 'QStartNoAckMode' 102 prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID 103 set_logging_mode, // 'QSetLogging:' 104 set_max_packet_size, // 'QSetMaxPacketSize:' 105 set_max_payload_size, // 'QSetMaxPayloadSize:' 106 set_environment_variable, // 'QEnvironment:' 107 set_environment_variable_hex, // 'QEnvironmentHexEncoded:' 108 set_launch_arch, // 'QLaunchArch:' 109 set_disable_aslr, // 'QSetDisableASLR:' 110 set_stdin, // 'QSetSTDIN:' 111 set_stdout, // 'QSetSTDOUT:' 112 set_stderr, // 'QSetSTDERR:' 113 set_working_dir, // 'QSetWorkingDir:' 114 set_list_threads_in_stop_reply, // 'QListThreadsInStopReply:' 115 sync_thread_state, // 'QSyncThreadState:' 116 memory_region_info, // 'qMemoryRegionInfo:' 117 get_profile_data, // 'qGetProfileData' 118 set_enable_profiling, // 'QSetEnableAsyncProfiling' 119 watchpoint_support_info, // 'qWatchpointSupportInfo:' 120 allocate_memory, // '_M' 121 deallocate_memory, // '_m' 122 123 unknown_type 124 } PacketEnum; 125 126 typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p); 127 128 RNBRemote (); 129 ~RNBRemote (); 130 131 void Initialize(); 132 133 bool InitializeRegisters (bool force = false); 134 135 rnb_err_t HandleAsyncPacket(PacketEnum *type = NULL); 136 rnb_err_t HandleReceivedPacket(PacketEnum *type = NULL); 137 138 nub_thread_t GetContinueThread () const 139 { 140 return m_continue_thread; 141 } 142 143 void SetContinueThread (nub_thread_t tid) 144 { 145 m_continue_thread = tid; 146 } 147 148 nub_thread_t GetCurrentThread () const 149 { 150 if (m_thread == 0 || m_thread == -1) 151 return DNBProcessGetCurrentThread (m_ctx.ProcessID()); 152 return m_thread; 153 } 154 155 void SetCurrentThread (nub_thread_t tid) 156 { 157 DNBProcessSetCurrentThread (m_ctx.ProcessID(), tid); 158 m_thread = tid; 159 } 160 161 static void* ThreadFunctionReadRemoteData(void *arg); 162 void StartReadRemoteDataThread (); 163 void StopReadRemoteDataThread (); 164 165 void NotifyThatProcessStopped (void); 166 167 rnb_err_t HandlePacket_A (const char *p); 168 rnb_err_t HandlePacket_H (const char *p); 169 rnb_err_t HandlePacket_qC (const char *p); 170 rnb_err_t HandlePacket_qRcmd (const char *p); 171 rnb_err_t HandlePacket_qGetPid (const char *p); 172 rnb_err_t HandlePacket_qLaunchSuccess (const char *p); 173 rnb_err_t HandlePacket_qRegisterInfo (const char *p); 174 rnb_err_t HandlePacket_qShlibInfoAddr (const char *p); 175 rnb_err_t HandlePacket_qStepPacketSupported (const char *p); 176 rnb_err_t HandlePacket_qVAttachOrWaitSupported (const char *p); 177 rnb_err_t HandlePacket_qSyncThreadStateSupported (const char *p); 178 rnb_err_t HandlePacket_qThreadInfo (const char *p); 179 rnb_err_t HandlePacket_qThreadExtraInfo (const char *p); 180 rnb_err_t HandlePacket_qThreadStopInfo (const char *p); 181 rnb_err_t HandlePacket_qHostInfo (const char *p); 182 rnb_err_t HandlePacket_qGDBServerVersion (const char *p); 183 rnb_err_t HandlePacket_qProcessInfo (const char *p); 184 rnb_err_t HandlePacket_QStartNoAckMode (const char *p); 185 rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p); 186 rnb_err_t HandlePacket_QSetLogging (const char *p); 187 rnb_err_t HandlePacket_QSetDisableASLR (const char *p); 188 rnb_err_t HandlePacket_QSetSTDIO (const char *p); 189 rnb_err_t HandlePacket_QSetWorkingDir (const char *p); 190 rnb_err_t HandlePacket_QSetMaxPayloadSize (const char *p); 191 rnb_err_t HandlePacket_QSetMaxPacketSize (const char *p); 192 rnb_err_t HandlePacket_QEnvironment (const char *p); 193 rnb_err_t HandlePacket_QEnvironmentHexEncoded (const char *p); 194 rnb_err_t HandlePacket_QLaunchArch (const char *p); 195 rnb_err_t HandlePacket_QListThreadsInStopReply (const char *p); 196 rnb_err_t HandlePacket_QSyncThreadState (const char *p); 197 rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p); 198 rnb_err_t HandlePacket_last_signal (const char *p); 199 rnb_err_t HandlePacket_m (const char *p); 200 rnb_err_t HandlePacket_M (const char *p); 201 rnb_err_t HandlePacket_X (const char *p); 202 rnb_err_t HandlePacket_g (const char *p); 203 rnb_err_t HandlePacket_G (const char *p); 204 rnb_err_t HandlePacket_z (const char *p); 205 rnb_err_t HandlePacket_T (const char *p); 206 rnb_err_t HandlePacket_p (const char *p); 207 rnb_err_t HandlePacket_P (const char *p); 208 rnb_err_t HandlePacket_c (const char *p); 209 rnb_err_t HandlePacket_C (const char *p); 210 rnb_err_t HandlePacket_D (const char *p); 211 rnb_err_t HandlePacket_k (const char *p); 212 rnb_err_t HandlePacket_s (const char *p); 213 rnb_err_t HandlePacket_S (const char *p); 214 rnb_err_t HandlePacket_v (const char *p); 215 rnb_err_t HandlePacket_UNIMPLEMENTED (const char *p); 216 rnb_err_t HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description); 217 rnb_err_t HandlePacket_AllocateMemory (const char *p); 218 rnb_err_t HandlePacket_DeallocateMemory (const char *p); 219 rnb_err_t HandlePacket_MemoryRegionInfo (const char *p); 220 rnb_err_t HandlePacket_GetProfileData(const char *p); 221 rnb_err_t HandlePacket_SetEnableAsyncProfiling(const char *p); 222 rnb_err_t HandlePacket_WatchpointSupportInfo (const char *p); 223 224 rnb_err_t HandlePacket_stop_process (const char *p); 225 226 rnb_err_t SendStopReplyPacketForThread (nub_thread_t tid); 227 rnb_err_t SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer); 228 rnb_err_t SendSTDOUTPacket (char *buf, nub_size_t buf_size); 229 rnb_err_t SendSTDERRPacket (char *buf, nub_size_t buf_size); 230 void FlushSTDIO (); 231 void SendAsyncProfileData (); 232 rnb_err_t SendAsyncProfileDataPacket (char *buf, nub_size_t buf_size); 233 234 RNBContext& Context() { return m_ctx; } 235 RNBSocket& Comm() { return m_comm; } 236 237 void 238 SetUseNativeRegisters (bool b) 239 { 240 m_use_native_regs = b; 241 } 242 private: 243 // Outlaw some contructors 244 RNBRemote (const RNBRemote &); 245 246 protected: 247 248 rnb_err_t GetCommData (); 249 void CommDataReceived(const std::string& data); 250 struct Packet 251 { 252 typedef std::vector<Packet> collection; 253 typedef collection::iterator iterator; 254 typedef collection::const_iterator const_iterator; 255 PacketEnum type; 256 HandlePacketCallback normal; // Function to call when inferior is halted 257 HandlePacketCallback async; // Function to call when inferior is running 258 std::string abbrev; 259 std::string printable_name; 260 261 bool 262 IsPlatformPacket () const 263 { 264 switch (type) 265 { 266 case set_logging_mode: 267 case query_host_info: 268 return true; 269 default: 270 break; 271 } 272 return false; 273 } 274 Packet() : 275 type(invalid_packet), 276 normal (NULL), 277 async (NULL), 278 abbrev (), 279 printable_name () 280 { 281 } 282 283 Packet( PacketEnum in_type, 284 HandlePacketCallback in_normal, 285 HandlePacketCallback in_async, 286 const char *in_abbrev, 287 const char *in_printable_name) : 288 type (in_type), 289 normal (in_normal), 290 async (in_async), 291 abbrev (in_abbrev), 292 printable_name (in_printable_name) 293 { 294 } 295 }; 296 297 rnb_err_t GetPacket (std::string &packet_data, RNBRemote::Packet& packet_info, bool wait); 298 rnb_err_t SendPacket (const std::string &); 299 300 void CreatePacketTable (); 301 rnb_err_t GetPacketPayload (std::string &); 302 303 nub_thread_t 304 ExtractThreadIDFromThreadSuffix (const char *p); 305 306 RNBContext m_ctx; // process context 307 RNBSocket m_comm; // communication port 308 std::string m_arch; 309 nub_thread_t m_continue_thread; // thread to continue; 0 for any, -1 for all 310 nub_thread_t m_thread; // thread for other ops; 0 for any, -1 for all 311 PThreadMutex m_mutex; // Mutex that protects 312 uint32_t m_packets_recvd; 313 Packet::collection m_packets; 314 std::deque<std::string> m_rx_packets; 315 std::string m_rx_partial_data; // For packets that may come in more than one batch, anything left over can be left here 316 pthread_t m_rx_pthread; 317 uint32_t m_max_payload_size; // the maximum sized payload we should send to gdb 318 bool m_extended_mode; // are we in extended mode? 319 bool m_noack_mode; // are we in no-ack mode? 320 bool m_use_native_regs; // Use native registers by querying DNB layer for register definitions? 321 bool m_thread_suffix_supported; // Set to true if the 'p', 'P', 'g', and 'G' packets should be prefixed with the thread ID and colon: 322 // "$pRR;thread:TTTT;" instead of "$pRR" 323 // "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV" 324 // "$g;thread:TTTT" instead of "$g" 325 // "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV" 326 bool m_list_threads_in_stop_reply; 327 }; 328 329 /* We translate the /usr/include/mach/exception_types.h exception types 330 (e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses 331 in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS). These hard 332 coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb 333 values in its include/gdb/signals.h. */ 334 335 #define TARGET_EXC_BAD_ACCESS 0x91 336 #define TARGET_EXC_BAD_INSTRUCTION 0x92 337 #define TARGET_EXC_ARITHMETIC 0x93 338 #define TARGET_EXC_EMULATION 0x94 339 #define TARGET_EXC_SOFTWARE 0x95 340 #define TARGET_EXC_BREAKPOINT 0x96 341 342 /* Generally speaking, you can't assume gdb can receive more than 399 bytes 343 at a time with a random gdb. This bufsize constant is only specifying 344 how many bytes gdb can *receive* from debugserver -- it tells us nothing 345 about how many bytes gdb might try to send in a single packet. */ 346 #define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399 347 348 #endif // #ifndef __RNBRemote_h__ 349