RNBRemote.h revision e1f50b9df1299f6b9181b5ac2699ed4a3ad38a59
127aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//===-- RNBRemote.h ---------------------------------------------*- C++ -*-===// 227aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// 327aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// The LLVM Compiler Infrastructure 427aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// 527aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// This file is distributed under the University of Illinois Open Source 627aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// License. See LICENSE.TXT for details. 727aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// 827aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//===----------------------------------------------------------------------===// 927aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// 1027aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// Created by Greg Clayton on 12/12/07. 1127aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// 1227aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//===----------------------------------------------------------------------===// 1327aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn 1427aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#ifndef __RNBRemote_h__ 1527aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#define __RNBRemote_h__ 1627aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn 1727aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "RNBDefs.h" 1827aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "DNB.h" 1927aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "RNBContext.h" 2027aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "RNBSocket.h" 2127aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "PThreadMutex.h" 2227aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include <string> 2327aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include <vector> 2427aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include <deque> 2527aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include <map> 2627aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn 2727aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornclass RNBSocket; 2827aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornclass RNBContext; 2927aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornclass PThreadEvents; 3027aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn 3127aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornenum event_loop_mode { debug_nub, gdb_remote_protocol, done }; 3227aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn 3327aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornclass RNBRemote 3427aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn{ 3527aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornpublic: 3627aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn 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 vattachname, // 'vAttachName:XX...' where XX is one or more hex encoded process name ASCII bytes 67 vcont, // 'vCont' 68 vcont_list_actions, // 'vCont?' 69 write_data_to_memory, // 'X' 70 insert_mem_bp, // 'Z0' 71 remove_mem_bp, // 'z0' 72 insert_hardware_bp, // 'Z1' 73 remove_hardware_bp, // 'z1' 74 insert_write_watch_bp, // 'Z2' 75 remove_write_watch_bp, // 'z2' 76 insert_read_watch_bp, // 'Z3' 77 remove_read_watch_bp, // 'z3' 78 insert_access_watch_bp, // 'Z4' 79 remove_access_watch_bp, // 'z4' 80 81 query_current_thread_id, // 'qC' 82 query_memory_crc, // 'qCRC:' 83 query_thread_ids_first, // 'qfThreadInfo' 84 query_thread_ids_subsequent, // 'qsThreadInfo' 85 query_thread_extra_info, // 'qThreadExtraInfo' 86 query_thread_stop_info, // 'qThreadStopInfo' 87 query_image_offsets, // 'qOffsets' 88 query_symbol_lookup, // 'gSymbols' 89 query_launch_success, // 'qLaunchSuccess' 90 query_register_info, // 'qRegisterInfo' 91 query_shlib_notify_info_addr, // 'qShlibInfoAddr' 92 query_step_packet_supported, // 'qStepPacketSupported' 93 query_host_info, // 'qHostInfo' 94 pass_signals_to_inferior, // 'QPassSignals' 95 start_noack_mode, // 'QStartNoAckMode' 96 prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID 97 set_logging_mode, // 'QSetLogging:' 98 set_max_packet_size, // 'QSetMaxPacketSize:' 99 set_max_payload_size, // 'QSetMaxPayloadSize:' 100 set_environment_variable, // 'QEnvironment:' 101 set_disable_aslr, // 'QSetDisableASLR:' 102 set_stdin, // 'QSetSTDIN:' 103 set_stdout, // 'QSetSTDOUT:' 104 set_stderr, // 'QSetSTDERR:' 105 set_working_dir, // 'QSetWorkingDir:' 106 allocate_memory, // '_M' 107 deallocate_memory, // '_m' 108 109 unknown_type, 110 } PacketEnum; 111 112 typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p); 113 114 RNBRemote (); 115 ~RNBRemote (); 116 117 void Initialize(); 118 119 bool InitializeRegisters (); 120 121 rnb_err_t HandleAsyncPacket(PacketEnum *type = NULL); 122 rnb_err_t HandleReceivedPacket(PacketEnum *type = NULL); 123 124 nub_thread_t GetContinueThread () const 125 { 126 return m_continue_thread; 127 } 128 129 void SetContinueThread (nub_thread_t tid) 130 { 131 m_continue_thread = tid; 132 } 133 134 nub_thread_t GetCurrentThread () const 135 { 136 if (m_thread == 0 || m_thread == -1) 137 return DNBProcessGetCurrentThread (m_ctx.ProcessID()); 138 return m_thread; 139 } 140 141 void SetCurrentThread (nub_thread_t tid) 142 { 143 DNBProcessSetCurrentThread (m_ctx.ProcessID(), tid); 144 m_thread = tid; 145 } 146 147 static void* ThreadFunctionReadRemoteData(void *arg); 148 void StartReadRemoteDataThread (); 149 void StopReadRemoteDataThread (); 150 151 void NotifyThatProcessStopped (void); 152 153 rnb_err_t HandlePacket_A (const char *p); 154 rnb_err_t HandlePacket_H (const char *p); 155 rnb_err_t HandlePacket_qC (const char *p); 156 rnb_err_t HandlePacket_qLaunchSuccess (const char *p); 157 rnb_err_t HandlePacket_qRegisterInfo (const char *p); 158 rnb_err_t HandlePacket_qShlibInfoAddr (const char *p); 159 rnb_err_t HandlePacket_qStepPacketSupported (const char *p); 160 rnb_err_t HandlePacket_qThreadInfo (const char *p); 161 rnb_err_t HandlePacket_qThreadExtraInfo (const char *p); 162 rnb_err_t HandlePacket_qThreadStopInfo (const char *p); 163 rnb_err_t HandlePacket_qHostInfo (const char *p); 164 rnb_err_t HandlePacket_QStartNoAckMode (const char *p); 165 rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p); 166 rnb_err_t HandlePacket_QSetLogging (const char *p); 167 rnb_err_t HandlePacket_QSetDisableASLR (const char *p); 168 rnb_err_t HandlePacket_QSetSTDIO (const char *p); 169 rnb_err_t HandlePacket_QSetWorkingDir (const char *p); 170 rnb_err_t HandlePacket_QSetMaxPayloadSize (const char *p); 171 rnb_err_t HandlePacket_QSetMaxPacketSize (const char *p); 172 rnb_err_t HandlePacket_QEnvironment (const char *p); 173 rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p); 174 rnb_err_t HandlePacket_last_signal (const char *p); 175 rnb_err_t HandlePacket_m (const char *p); 176 rnb_err_t HandlePacket_M (const char *p); 177 rnb_err_t HandlePacket_X (const char *p); 178 rnb_err_t HandlePacket_g (const char *p); 179 rnb_err_t HandlePacket_G (const char *p); 180 rnb_err_t HandlePacket_z (const char *p); 181 rnb_err_t HandlePacket_T (const char *p); 182 rnb_err_t HandlePacket_p (const char *p); 183 rnb_err_t HandlePacket_P (const char *p); 184 rnb_err_t HandlePacket_c (const char *p); 185 rnb_err_t HandlePacket_C (const char *p); 186 rnb_err_t HandlePacket_D (const char *p); 187 rnb_err_t HandlePacket_k (const char *p); 188 rnb_err_t HandlePacket_s (const char *p); 189 rnb_err_t HandlePacket_S (const char *p); 190 rnb_err_t HandlePacket_v (const char *p); 191 rnb_err_t HandlePacket_UNIMPLEMENTED (const char *p); 192 rnb_err_t HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description); 193 rnb_err_t HandlePacket_AllocateMemory (const char *p); 194 rnb_err_t HandlePacket_DeallocateMemory (const char *p); 195 196 rnb_err_t HandlePacket_stop_process (const char *p); 197 198 rnb_err_t SendStopReplyPacketForThread (nub_thread_t tid); 199 rnb_err_t SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer); 200 rnb_err_t SendSTDOUTPacket (char *buf, nub_size_t buf_size); 201 rnb_err_t SendSTDERRPacket (char *buf, nub_size_t buf_size); 202 void FlushSTDIO (); 203 204 RNBContext& Context() { return m_ctx; } 205 RNBSocket& Comm() { return m_comm; } 206 207 void 208 SetUseNativeRegisters (bool b) 209 { 210 m_use_native_regs = b; 211 } 212private: 213 // Outlaw some contructors 214 RNBRemote (const RNBRemote &); 215 216protected: 217 218 rnb_err_t GetCommData (); 219 void CommDataReceived(const std::string& data); 220 struct Packet 221 { 222 typedef std::vector<Packet> collection; 223 typedef collection::iterator iterator; 224 typedef collection::const_iterator const_iterator; 225 PacketEnum type; 226 HandlePacketCallback normal; // Function to call when inferior is halted 227 HandlePacketCallback async; // Function to call when inferior is running 228 std::string abbrev; 229 std::string printable_name; 230 231 bool 232 IsPlatformPacket () const 233 { 234 switch (type) 235 { 236 case set_logging_mode: 237 case query_host_info: 238 return true; 239 default: 240 break; 241 } 242 return false; 243 } 244 Packet() : 245 type(invalid_packet), 246 normal (NULL), 247 async (NULL), 248 abbrev (), 249 printable_name () 250 { 251 } 252 253 Packet( PacketEnum in_type, 254 HandlePacketCallback in_normal, 255 HandlePacketCallback in_async, 256 const char *in_abbrev, 257 const char *in_printable_name) : 258 type (in_type), 259 normal (in_normal), 260 async (in_async), 261 abbrev (in_abbrev), 262 printable_name (in_printable_name) 263 { 264 } 265 }; 266 267 rnb_err_t GetPacket (std::string &packet_data, RNBRemote::Packet& packet_info, bool wait); 268 rnb_err_t SendPacket (const std::string &); 269 270 void CreatePacketTable (); 271 rnb_err_t GetPacketPayload (std::string &); 272 273 nub_thread_t 274 ExtractThreadIDFromThreadSuffix (const char *p); 275 276 // gdb can send multiple Z/z packets for the same address and 277 // these calls must be ref counted. 278 struct Breakpoint 279 { 280 Breakpoint(nub_break_t breakID) : 281 m_breakID(breakID), 282 m_refCount(1) 283 { 284 } 285 286 Breakpoint() : 287 m_breakID(INVALID_NUB_BREAK_ID), 288 m_refCount(0) 289 { 290 } 291 292 Breakpoint(const Breakpoint& rhs) : 293 m_breakID(rhs.m_breakID), 294 m_refCount(rhs.m_refCount) 295 { 296 } 297 298 nub_break_t BreakID() const { return m_breakID; } 299 uint32_t RefCount() const { return m_refCount; } 300 void Release() { if (m_refCount > 0) --m_refCount; } 301 void Retain() { ++m_refCount; } 302 303 nub_break_t m_breakID; 304 uint32_t m_refCount; 305 }; 306 typedef std::map<nub_addr_t, Breakpoint> BreakpointMap; 307 typedef BreakpointMap::iterator BreakpointMapIter; 308 typedef BreakpointMap::const_iterator BreakpointMapConstIter; 309 RNBContext m_ctx; // process context 310 RNBSocket m_comm; // communication port 311 std::string m_arch; 312 nub_thread_t m_continue_thread; // thread to continue; 0 for any, -1 for all 313 nub_thread_t m_thread; // thread for other ops; 0 for any, -1 for all 314 PThreadMutex m_mutex; // Mutex that protects 315 uint32_t m_packets_recvd; 316 Packet::collection m_packets; 317 std::deque<std::string> m_rx_packets; 318 std::string m_rx_partial_data; // For packets that may come in more than one batch, anything left over can be left here 319 pthread_t m_rx_pthread; 320 BreakpointMap m_breakpoints; 321 BreakpointMap m_watchpoints; 322 uint32_t m_max_payload_size; // the maximum sized payload we should send to gdb 323 bool m_extended_mode:1, // are we in extended mode? 324 m_noack_mode:1, // are we in no-ack mode? 325 m_noack_mode_just_enabled:1, // Did we just enable this and need to compute one more checksum? 326 m_use_native_regs:1, // Use native registers by querying DNB layer for register definitions? 327 m_thread_suffix_supported:1; // Set to true if the 'p', 'P', 'g', and 'G' packets should be prefixed with the thread ID and colon: 328 // "$pRR;thread:TTTT;" instead of "$pRR" 329 // "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV" 330 // "$g;thread:TTTT" instead of "$g" 331 // "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV" 332}; 333 334/* We translate the /usr/include/mach/exception_types.h exception types 335 (e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses 336 in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS). These hard 337 coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb 338 values in its include/gdb/signals.h. */ 339 340#define TARGET_EXC_BAD_ACCESS 0x91 341#define TARGET_EXC_BAD_INSTRUCTION 0x92 342#define TARGET_EXC_ARITHMETIC 0x93 343#define TARGET_EXC_EMULATION 0x94 344#define TARGET_EXC_SOFTWARE 0x95 345#define TARGET_EXC_BREAKPOINT 0x96 346 347/* Generally speaking, you can't assume gdb can receive more than 399 bytes 348 at a time with a random gdb. This bufsize constant is only specifying 349 how many bytes gdb can *receive* from debugserver -- it tells us nothing 350 about how many bytes gdb might try to send in a single packet. */ 351#define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399 352 353#endif // #ifndef __RNBRemote_h__ 354