1 //===-- RNBRemote.cpp -------------------------------------------*- 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 #include "RNBRemote.h" 15 16 #include <errno.h> 17 #include <unistd.h> 18 #include <signal.h> 19 #include <mach/exception_types.h> 20 #include <sys/stat.h> 21 #include <sys/sysctl.h> 22 23 #include "DNB.h" 24 #include "DNBLog.h" 25 #include "DNBThreadResumeActions.h" 26 #include "RNBContext.h" 27 #include "RNBServices.h" 28 #include "RNBSocket.h" 29 #include "Utility/StringExtractor.h" 30 31 #include <iomanip> 32 #include <sstream> 33 #include <TargetConditionals.h> // for endianness predefines 34 35 //---------------------------------------------------------------------- 36 // std::iostream formatting macros 37 //---------------------------------------------------------------------- 38 #define RAW_HEXBASE std::setfill('0') << std::hex << std::right 39 #define HEXBASE '0' << 'x' << RAW_HEXBASE 40 #define RAWHEX8(x) RAW_HEXBASE << std::setw(2) << ((uint32_t)((uint8_t)x)) 41 #define RAWHEX16 RAW_HEXBASE << std::setw(4) 42 #define RAWHEX32 RAW_HEXBASE << std::setw(8) 43 #define RAWHEX64 RAW_HEXBASE << std::setw(16) 44 #define HEX8(x) HEXBASE << std::setw(2) << ((uint32_t)(x)) 45 #define HEX16 HEXBASE << std::setw(4) 46 #define HEX32 HEXBASE << std::setw(8) 47 #define HEX64 HEXBASE << std::setw(16) 48 #define RAW_HEX(x) RAW_HEXBASE << std::setw(sizeof(x)*2) << (x) 49 #define HEX(x) HEXBASE << std::setw(sizeof(x)*2) << (x) 50 #define RAWHEX_SIZE(x, sz) RAW_HEXBASE << std::setw((sz)) << (x) 51 #define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x) 52 #define STRING_WIDTH(w) std::setfill(' ') << std::setw(w) 53 #define LEFT_STRING_WIDTH(s, w) std::left << std::setfill(' ') << std::setw(w) << (s) << std::right 54 #define DECIMAL std::dec << std::setfill(' ') 55 #define DECIMAL_WIDTH(w) DECIMAL << std::setw(w) 56 #define FLOAT(n, d) std::setfill(' ') << std::setw((n)+(d)+1) << std::setprecision(d) << std::showpoint << std::fixed 57 #define INDENT_WITH_SPACES(iword_idx) std::setfill(' ') << std::setw((iword_idx)) << "" 58 #define INDENT_WITH_TABS(iword_idx) std::setfill('\t') << std::setw((iword_idx)) << "" 59 // Class to handle communications via gdb remote protocol. 60 61 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); 62 63 RNBRemote::RNBRemote () : 64 m_ctx (), 65 m_comm (), 66 m_continue_thread(-1), 67 m_thread(-1), 68 m_mutex(), 69 m_packets_recvd(0), 70 m_packets(), 71 m_rx_packets(), 72 m_rx_partial_data(), 73 m_rx_pthread(0), 74 m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4), 75 m_extended_mode(false), 76 m_noack_mode(false), 77 m_thread_suffix_supported (false), 78 m_list_threads_in_stop_reply (false) 79 { 80 DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); 81 CreatePacketTable (); 82 } 83 84 85 RNBRemote::~RNBRemote() 86 { 87 DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__); 88 StopReadRemoteDataThread(); 89 } 90 91 void 92 RNBRemote::CreatePacketTable () 93 { 94 // Step required to add new packets: 95 // 1 - Add new enumeration to RNBRemote::PacketEnum 96 // 2 - Create a the RNBRemote::HandlePacket_ function if a new function is needed 97 // 3 - Register the Packet definition with any needed callbacks in this function 98 // - If no response is needed for a command, then use NULL for the normal callback 99 // - If the packet is not supported while the target is running, use NULL for the async callback 100 // 4 - If the packet is a standard packet (starts with a '$' character 101 // followed by the payload and then '#' and checksum, then you are done 102 // else go on to step 5 103 // 5 - if the packet is a fixed length packet: 104 // - modify the switch statement for the first character in the payload 105 // in RNBRemote::CommDataReceived so it doesn't reject the new packet 106 // type as invalid 107 // - modify the switch statement for the first character in the payload 108 // in RNBRemote::GetPacketPayload and make sure the payload of the packet 109 // is returned correctly 110 111 std::vector <Packet> &t = m_packets; 112 t.push_back (Packet (ack, NULL, NULL, "+", "ACK")); 113 t.push_back (Packet (nack, NULL, NULL, "-", "!ACK")); 114 t.push_back (Packet (read_memory, &RNBRemote::HandlePacket_m, NULL, "m", "Read memory")); 115 t.push_back (Packet (read_register, &RNBRemote::HandlePacket_p, NULL, "p", "Read one register")); 116 t.push_back (Packet (read_general_regs, &RNBRemote::HandlePacket_g, NULL, "g", "Read registers")); 117 t.push_back (Packet (write_memory, &RNBRemote::HandlePacket_M, NULL, "M", "Write memory")); 118 t.push_back (Packet (write_register, &RNBRemote::HandlePacket_P, NULL, "P", "Write one register")); 119 t.push_back (Packet (write_general_regs, &RNBRemote::HandlePacket_G, NULL, "G", "Write registers")); 120 t.push_back (Packet (insert_mem_bp, &RNBRemote::HandlePacket_z, NULL, "Z0", "Insert memory breakpoint")); 121 t.push_back (Packet (remove_mem_bp, &RNBRemote::HandlePacket_z, NULL, "z0", "Remove memory breakpoint")); 122 t.push_back (Packet (single_step, &RNBRemote::HandlePacket_s, NULL, "s", "Single step")); 123 t.push_back (Packet (cont, &RNBRemote::HandlePacket_c, NULL, "c", "continue")); 124 t.push_back (Packet (single_step_with_sig, &RNBRemote::HandlePacket_S, NULL, "S", "Single step with signal")); 125 t.push_back (Packet (set_thread, &RNBRemote::HandlePacket_H, NULL, "H", "Set thread")); 126 t.push_back (Packet (halt, &RNBRemote::HandlePacket_last_signal, &RNBRemote::HandlePacket_stop_process, "\x03", "^C")); 127 // t.push_back (Packet (use_extended_mode, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "!", "Use extended mode")); 128 t.push_back (Packet (why_halted, &RNBRemote::HandlePacket_last_signal, NULL, "?", "Why did target halt")); 129 t.push_back (Packet (set_argv, &RNBRemote::HandlePacket_A, NULL, "A", "Set argv")); 130 // t.push_back (Packet (set_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "B", "Set/clear breakpoint")); 131 t.push_back (Packet (continue_with_sig, &RNBRemote::HandlePacket_C, NULL, "C", "Continue with signal")); 132 t.push_back (Packet (detach, &RNBRemote::HandlePacket_D, NULL, "D", "Detach gdb from remote system")); 133 // t.push_back (Packet (step_inferior_one_cycle, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "i", "Step inferior by one clock cycle")); 134 // t.push_back (Packet (signal_and_step_inf_one_cycle, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "I", "Signal inferior, then step one clock cyle")); 135 t.push_back (Packet (kill, &RNBRemote::HandlePacket_k, NULL, "k", "Kill")); 136 // t.push_back (Packet (restart, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "R", "Restart inferior")); 137 // t.push_back (Packet (search_mem_backwards, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "t", "Search memory backwards")); 138 t.push_back (Packet (thread_alive_p, &RNBRemote::HandlePacket_T, NULL, "T", "Is thread alive")); 139 t.push_back (Packet (vattach, &RNBRemote::HandlePacket_v, NULL, "vAttach", "Attach to a new process")); 140 t.push_back (Packet (vattachwait, &RNBRemote::HandlePacket_v, NULL, "vAttachWait", "Wait for a process to start up then attach to it")); 141 t.push_back (Packet (vattachorwait, &RNBRemote::HandlePacket_v, NULL, "vAttachOrWait", "Attach to the process or if it doesn't exist, wait for the process to start up then attach to it")); 142 t.push_back (Packet (vattachname, &RNBRemote::HandlePacket_v, NULL, "vAttachName", "Attach to an existing process by name")); 143 t.push_back (Packet (vcont_list_actions, &RNBRemote::HandlePacket_v, NULL, "vCont;", "Verbose resume with thread actions")); 144 t.push_back (Packet (vcont_list_actions, &RNBRemote::HandlePacket_v, NULL, "vCont?", "List valid continue-with-thread-actions actions")); 145 // The X packet doesn't currently work. If/when it does, remove the line above and uncomment out the line below 146 // t.push_back (Packet (write_data_to_memory, &RNBRemote::HandlePacket_X, NULL, "X", "Write data to memory")); 147 // t.push_back (Packet (insert_hardware_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware breakpoint")); 148 // t.push_back (Packet (remove_hardware_bp, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware breakpoint")); 149 t.push_back (Packet (insert_write_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z2", "Insert write watchpoint")); 150 t.push_back (Packet (remove_write_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z2", "Remove write watchpoint")); 151 t.push_back (Packet (insert_read_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z3", "Insert read watchpoint")); 152 t.push_back (Packet (remove_read_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z3", "Remove read watchpoint")); 153 t.push_back (Packet (insert_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z4", "Insert access watchpoint")); 154 t.push_back (Packet (remove_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z4", "Remove access watchpoint")); 155 t.push_back (Packet (query_monitor, &RNBRemote::HandlePacket_qRcmd, NULL, "qRcmd", "Monitor command")); 156 t.push_back (Packet (query_current_thread_id, &RNBRemote::HandlePacket_qC, NULL, "qC", "Query current thread ID")); 157 t.push_back (Packet (query_get_pid, &RNBRemote::HandlePacket_qGetPid, NULL, "qGetPid", "Query process id")); 158 t.push_back (Packet (query_thread_ids_first, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qfThreadInfo", "Get list of active threads (first req)")); 159 t.push_back (Packet (query_thread_ids_subsequent, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qsThreadInfo", "Get list of active threads (subsequent req)")); 160 // APPLE LOCAL: qThreadStopInfo 161 // syntax: qThreadStopInfoTTTT 162 // TTTT is hex thread ID 163 t.push_back (Packet (query_thread_stop_info, &RNBRemote::HandlePacket_qThreadStopInfo, NULL, "qThreadStopInfo", "Get detailed info on why the specified thread stopped")); 164 t.push_back (Packet (query_thread_extra_info, &RNBRemote::HandlePacket_qThreadExtraInfo,NULL, "qThreadExtraInfo", "Get printable status of a thread")); 165 // t.push_back (Packet (query_image_offsets, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qOffsets", "Report offset of loaded program")); 166 t.push_back (Packet (query_launch_success, &RNBRemote::HandlePacket_qLaunchSuccess,NULL, "qLaunchSuccess", "Report the success or failure of the launch attempt")); 167 t.push_back (Packet (query_register_info, &RNBRemote::HandlePacket_qRegisterInfo, NULL, "qRegisterInfo", "Dynamically discover remote register context information.")); 168 t.push_back (Packet (query_shlib_notify_info_addr, &RNBRemote::HandlePacket_qShlibInfoAddr,NULL, "qShlibInfoAddr", "Returns the address that contains info needed for getting shared library notifications")); 169 t.push_back (Packet (query_step_packet_supported, &RNBRemote::HandlePacket_qStepPacketSupported,NULL, "qStepPacketSupported", "Replys with OK if the 's' packet is supported.")); 170 t.push_back (Packet (query_vattachorwait_supported, &RNBRemote::HandlePacket_qVAttachOrWaitSupported,NULL, "qVAttachOrWaitSupported", "Replys with OK if the 'vAttachOrWait' packet is supported.")); 171 t.push_back (Packet (query_sync_thread_state_supported, &RNBRemote::HandlePacket_qSyncThreadStateSupported,NULL, "qSyncThreadStateSupported", "Replys with OK if the 'QSyncThreadState:' packet is supported.")); 172 t.push_back (Packet (query_host_info, &RNBRemote::HandlePacket_qHostInfo, NULL, "qHostInfo", "Replies with multiple 'key:value;' tuples appended to each other.")); 173 t.push_back (Packet (query_gdb_server_version, &RNBRemote::HandlePacket_qGDBServerVersion, NULL, "qGDBServerVersion", "Replies with multiple 'key:value;' tuples appended to each other.")); 174 t.push_back (Packet (query_process_info, &RNBRemote::HandlePacket_qProcessInfo, NULL, "qProcessInfo", "Replies with multiple 'key:value;' tuples appended to each other.")); 175 // t.push_back (Packet (query_symbol_lookup, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qSymbol", "Notify that host debugger is ready to do symbol lookups")); 176 t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets")); 177 t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specifc packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command")); 178 t.push_back (Packet (set_logging_mode, &RNBRemote::HandlePacket_QSetLogging , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix")); 179 t.push_back (Packet (set_max_packet_size, &RNBRemote::HandlePacket_QSetMaxPacketSize , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle")); 180 t.push_back (Packet (set_max_payload_size, &RNBRemote::HandlePacket_QSetMaxPayloadSize , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle")); 181 t.push_back (Packet (set_environment_variable, &RNBRemote::HandlePacket_QEnvironment , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment")); 182 t.push_back (Packet (set_environment_variable_hex, &RNBRemote::HandlePacket_QEnvironmentHexEncoded , NULL, "QEnvironmentHexEncoded:", "Add an environment variable to the inferior's environment")); 183 t.push_back (Packet (set_launch_arch, &RNBRemote::HandlePacket_QLaunchArch , NULL, "QLaunchArch:", "Set the architecture to use when launching a process for hosts that can run multiple architecture slices from universal files.")); 184 t.push_back (Packet (set_disable_aslr, &RNBRemote::HandlePacket_QSetDisableASLR , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet")); 185 t.push_back (Packet (set_stdin, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDIN:", "Set the standard input for a process to be launched with the 'A' packet")); 186 t.push_back (Packet (set_stdout, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDOUT:", "Set the standard output for a process to be launched with the 'A' packet")); 187 t.push_back (Packet (set_stderr, &RNBRemote::HandlePacket_QSetSTDIO , NULL, "QSetSTDERR:", "Set the standard error for a process to be launched with the 'A' packet")); 188 t.push_back (Packet (set_working_dir, &RNBRemote::HandlePacket_QSetWorkingDir , NULL, "QSetWorkingDir:", "Set the working directory for a process to be launched with the 'A' packet")); 189 t.push_back (Packet (set_list_threads_in_stop_reply,&RNBRemote::HandlePacket_QListThreadsInStopReply , NULL, "QListThreadsInStopReply", "Set if the 'threads' key should be added to the stop reply packets with a list of all thread IDs.")); 190 t.push_back (Packet (sync_thread_state, &RNBRemote::HandlePacket_QSyncThreadState , NULL, "QSyncThreadState:", "Do whatever is necessary to make sure 'thread' is in a safe state to call functions on.")); 191 // t.push_back (Packet (pass_signals_to_inferior, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior")); 192 t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process.")); 193 t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process.")); 194 t.push_back (Packet (save_register_state, &RNBRemote::HandlePacket_SaveRegisterState, NULL, "QSaveRegisterState", "Save the register state for the current thread and return a decimal save ID.")); 195 t.push_back (Packet (restore_register_state, &RNBRemote::HandlePacket_RestoreRegisterState, NULL, "QRestoreRegisterState:", "Restore the register state given a save ID previosly returned from a call to QSaveRegisterState.")); 196 t.push_back (Packet (memory_region_info, &RNBRemote::HandlePacket_MemoryRegionInfo, NULL, "qMemoryRegionInfo", "Return size and attributes of a memory region that contains the given address")); 197 t.push_back (Packet (get_profile_data, &RNBRemote::HandlePacket_GetProfileData, NULL, "qGetProfileData", "Return profiling data of the current target.")); 198 t.push_back (Packet (set_enable_profiling, &RNBRemote::HandlePacket_SetEnableAsyncProfiling, NULL, "QSetEnableAsyncProfiling", "Enable or disable the profiling of current target.")); 199 t.push_back (Packet (watchpoint_support_info, &RNBRemote::HandlePacket_WatchpointSupportInfo, NULL, "qWatchpointSupportInfo", "Return the number of supported hardware watchpoints")); 200 201 } 202 203 204 void 205 RNBRemote::FlushSTDIO () 206 { 207 if (m_ctx.HasValidProcessID()) 208 { 209 nub_process_t pid = m_ctx.ProcessID(); 210 char buf[256]; 211 nub_size_t count; 212 do 213 { 214 count = DNBProcessGetAvailableSTDOUT(pid, buf, sizeof(buf)); 215 if (count > 0) 216 { 217 SendSTDOUTPacket (buf, count); 218 } 219 } while (count > 0); 220 221 do 222 { 223 count = DNBProcessGetAvailableSTDERR(pid, buf, sizeof(buf)); 224 if (count > 0) 225 { 226 SendSTDERRPacket (buf, count); 227 } 228 } while (count > 0); 229 } 230 } 231 232 void 233 RNBRemote::SendAsyncProfileData () 234 { 235 if (m_ctx.HasValidProcessID()) 236 { 237 nub_process_t pid = m_ctx.ProcessID(); 238 char buf[1024]; 239 nub_size_t count; 240 do 241 { 242 count = DNBProcessGetAvailableProfileData(pid, buf, sizeof(buf)); 243 if (count > 0) 244 { 245 SendAsyncProfileDataPacket (buf, count); 246 } 247 } while (count > 0); 248 } 249 } 250 251 rnb_err_t 252 RNBRemote::SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer) 253 { 254 std::ostringstream packet_sstrm; 255 // Append the header cstr if there was one 256 if (header && header[0]) 257 packet_sstrm << header; 258 nub_size_t i; 259 const uint8_t *ubuf8 = (const uint8_t *)buf; 260 for (i=0; i<buf_len; i++) 261 { 262 packet_sstrm << RAWHEX8(ubuf8[i]); 263 } 264 // Append the footer cstr if there was one 265 if (footer && footer[0]) 266 packet_sstrm << footer; 267 268 return SendPacket(packet_sstrm.str()); 269 } 270 271 rnb_err_t 272 RNBRemote::SendSTDOUTPacket (char *buf, nub_size_t buf_size) 273 { 274 if (buf_size == 0) 275 return rnb_success; 276 return SendHexEncodedBytePacket("O", buf, buf_size, NULL); 277 } 278 279 rnb_err_t 280 RNBRemote::SendSTDERRPacket (char *buf, nub_size_t buf_size) 281 { 282 if (buf_size == 0) 283 return rnb_success; 284 return SendHexEncodedBytePacket("O", buf, buf_size, NULL); 285 } 286 287 // This makes use of asynchronous bit 'A' in the gdb remote protocol. 288 rnb_err_t 289 RNBRemote::SendAsyncProfileDataPacket (char *buf, nub_size_t buf_size) 290 { 291 if (buf_size == 0) 292 return rnb_success; 293 294 std::string packet("A"); 295 packet.append(buf, buf_size); 296 return SendPacket(packet); 297 } 298 299 rnb_err_t 300 RNBRemote::SendPacket (const std::string &s) 301 { 302 DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s (%s) called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, s.c_str()); 303 std::string sendpacket = "$" + s + "#"; 304 int cksum = 0; 305 char hexbuf[5]; 306 307 if (m_noack_mode) 308 { 309 sendpacket += "00"; 310 } 311 else 312 { 313 for (int i = 0; i != s.size(); ++i) 314 cksum += s[i]; 315 snprintf (hexbuf, sizeof hexbuf, "%02x", cksum & 0xff); 316 sendpacket += hexbuf; 317 } 318 319 rnb_err_t err = m_comm.Write (sendpacket.c_str(), sendpacket.size()); 320 if (err != rnb_success) 321 return err; 322 323 if (m_noack_mode) 324 return rnb_success; 325 326 std::string reply; 327 RNBRemote::Packet packet; 328 err = GetPacket (reply, packet, true); 329 330 if (err != rnb_success) 331 { 332 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s (%s) got error trying to get reply...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, sendpacket.c_str()); 333 return err; 334 } 335 336 DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s (%s) got reply: '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, sendpacket.c_str(), reply.c_str()); 337 338 if (packet.type == ack) 339 return rnb_success; 340 341 // Should we try to resend the packet at this layer? 342 // if (packet.command == nack) 343 return rnb_err; 344 } 345 346 /* Get a packet via gdb remote protocol. 347 Strip off the prefix/suffix, verify the checksum to make sure 348 a valid packet was received, send an ACK if they match. */ 349 350 rnb_err_t 351 RNBRemote::GetPacketPayload (std::string &return_packet) 352 { 353 //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 354 355 PThreadMutex::Locker locker(m_mutex); 356 if (m_rx_packets.empty()) 357 { 358 // Only reset the remote command available event if we have no more packets 359 m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available ); 360 //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s error: no packets available...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 361 return rnb_err; 362 } 363 364 //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s has %u queued packets", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, m_rx_packets.size()); 365 return_packet.swap(m_rx_packets.front()); 366 m_rx_packets.pop_front(); 367 locker.Reset(); // Release our lock on the mutex 368 369 if (m_rx_packets.empty()) 370 { 371 // Reset the remote command available event if we have no more packets 372 m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available ); 373 } 374 375 //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s: '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str()); 376 377 switch (return_packet[0]) 378 { 379 case '+': 380 case '-': 381 case '\x03': 382 break; 383 384 case '$': 385 { 386 int packet_checksum = 0; 387 if (!m_noack_mode) 388 { 389 for (int i = return_packet.size() - 2; i < return_packet.size(); ++i) 390 { 391 char checksum_char = tolower (return_packet[i]); 392 if (!isxdigit (checksum_char)) 393 { 394 m_comm.Write ("-", 1); 395 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s error: packet with invalid checksum characters: %s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str()); 396 return rnb_err; 397 } 398 } 399 packet_checksum = strtol (&return_packet[return_packet.size() - 2], NULL, 16); 400 } 401 402 return_packet.erase(0,1); // Strip the leading '$' 403 return_packet.erase(return_packet.size() - 3);// Strip the #XX checksum 404 405 if (!m_noack_mode) 406 { 407 // Compute the checksum 408 int computed_checksum = 0; 409 for (std::string::iterator it = return_packet.begin (); 410 it != return_packet.end (); 411 ++it) 412 { 413 computed_checksum += *it; 414 } 415 416 if (packet_checksum == (computed_checksum & 0xff)) 417 { 418 //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str()); 419 m_comm.Write ("+", 1); 420 } 421 else 422 { 423 DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s' (error: packet checksum mismatch (0x%2.2x != 0x%2.2x))", 424 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), 425 __FUNCTION__, 426 return_packet.c_str(), 427 packet_checksum, 428 computed_checksum); 429 m_comm.Write ("-", 1); 430 return rnb_err; 431 } 432 } 433 } 434 break; 435 436 default: 437 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s tossing unexpected packet???? %s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str()); 438 if (!m_noack_mode) 439 m_comm.Write ("-", 1); 440 return rnb_err; 441 } 442 443 return rnb_success; 444 } 445 446 rnb_err_t 447 RNBRemote::HandlePacket_UNIMPLEMENTED (const char* p) 448 { 449 DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s(\"%s\")", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p ? p : "NULL"); 450 return SendPacket (""); 451 } 452 453 rnb_err_t 454 RNBRemote::HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description) 455 { 456 DNBLogThreadedIf (LOG_RNB_PACKETS, "%8u %s:%i ILLFORMED: '%s' (%s)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), file, line, __FUNCTION__, p); 457 return SendPacket ("E03"); 458 } 459 460 rnb_err_t 461 RNBRemote::GetPacket (std::string &packet_payload, RNBRemote::Packet& packet_info, bool wait) 462 { 463 std::string payload; 464 rnb_err_t err = GetPacketPayload (payload); 465 if (err != rnb_success) 466 { 467 PThreadEvent& events = m_ctx.Events(); 468 nub_event_t set_events = events.GetEventBits(); 469 // TODO: add timeout version of GetPacket?? We would then need to pass 470 // that timeout value along to DNBProcessTimedWaitForEvent. 471 if (!wait || ((set_events & RNBContext::event_read_thread_running) == 0)) 472 return err; 473 474 const nub_event_t events_to_wait_for = RNBContext::event_read_packet_available | RNBContext::event_read_thread_exiting; 475 476 while ((set_events = events.WaitForSetEvents(events_to_wait_for)) != 0) 477 { 478 if (set_events & RNBContext::event_read_packet_available) 479 { 480 // Try the queue again now that we got an event 481 err = GetPacketPayload (payload); 482 if (err == rnb_success) 483 break; 484 } 485 486 if (set_events & RNBContext::event_read_thread_exiting) 487 err = rnb_not_connected; 488 489 if (err == rnb_not_connected) 490 return err; 491 492 } while (err == rnb_err); 493 494 if (set_events == 0) 495 err = rnb_not_connected; 496 } 497 498 if (err == rnb_success) 499 { 500 Packet::iterator it; 501 for (it = m_packets.begin (); it != m_packets.end (); ++it) 502 { 503 if (payload.compare (0, it->abbrev.size(), it->abbrev) == 0) 504 break; 505 } 506 507 // A packet we don't have an entry for. This can happen when we 508 // get a packet that we don't know about or support. We just reply 509 // accordingly and go on. 510 if (it == m_packets.end ()) 511 { 512 DNBLogThreadedIf (LOG_RNB_PACKETS, "unimplemented packet: '%s'", payload.c_str()); 513 HandlePacket_UNIMPLEMENTED(payload.c_str()); 514 return rnb_err; 515 } 516 else 517 { 518 packet_info = *it; 519 packet_payload = payload; 520 } 521 } 522 return err; 523 } 524 525 rnb_err_t 526 RNBRemote::HandleAsyncPacket(PacketEnum *type) 527 { 528 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 529 static DNBTimer g_packetTimer(true); 530 rnb_err_t err = rnb_err; 531 std::string packet_data; 532 RNBRemote::Packet packet_info; 533 err = GetPacket (packet_data, packet_info, false); 534 535 if (err == rnb_success) 536 { 537 if (!packet_data.empty() && isprint(packet_data[0])) 538 DNBLogThreadedIf (LOG_RNB_REMOTE | LOG_RNB_PACKETS, "HandleAsyncPacket (\"%s\");", packet_data.c_str()); 539 else 540 DNBLogThreadedIf (LOG_RNB_REMOTE | LOG_RNB_PACKETS, "HandleAsyncPacket (%s);", packet_info.printable_name.c_str()); 541 542 HandlePacketCallback packet_callback = packet_info.async; 543 if (packet_callback != NULL) 544 { 545 if (type != NULL) 546 *type = packet_info.type; 547 return (this->*packet_callback)(packet_data.c_str()); 548 } 549 } 550 551 return err; 552 } 553 554 rnb_err_t 555 RNBRemote::HandleReceivedPacket(PacketEnum *type) 556 { 557 static DNBTimer g_packetTimer(true); 558 559 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 560 rnb_err_t err = rnb_err; 561 std::string packet_data; 562 RNBRemote::Packet packet_info; 563 err = GetPacket (packet_data, packet_info, false); 564 565 if (err == rnb_success) 566 { 567 DNBLogThreadedIf (LOG_RNB_REMOTE, "HandleReceivedPacket (\"%s\");", packet_data.c_str()); 568 HandlePacketCallback packet_callback = packet_info.normal; 569 if (packet_callback != NULL) 570 { 571 if (type != NULL) 572 *type = packet_info.type; 573 return (this->*packet_callback)(packet_data.c_str()); 574 } 575 else 576 { 577 // Do not fall through to end of this function, if we have valid 578 // packet_info and it has a NULL callback, then we need to respect 579 // that it may not want any response or anything to be done. 580 return err; 581 } 582 } 583 return rnb_err; 584 } 585 586 void 587 RNBRemote::CommDataReceived(const std::string& new_data) 588 { 589 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 590 { 591 // Put the packet data into the buffer in a thread safe fashion 592 PThreadMutex::Locker locker(m_mutex); 593 594 std::string data; 595 // See if we have any left over data from a previous call to this 596 // function? 597 if (!m_rx_partial_data.empty()) 598 { 599 // We do, so lets start with that data 600 data.swap(m_rx_partial_data); 601 } 602 // Append the new incoming data 603 data += new_data; 604 605 // Parse up the packets into gdb remote packets 606 uint32_t idx = 0; 607 const size_t data_size = data.size(); 608 609 while (idx < data_size) 610 { 611 // end_idx must be one past the last valid packet byte. Start 612 // it off with an invalid value that is the same as the current 613 // index. 614 size_t end_idx = idx; 615 616 switch (data[idx]) 617 { 618 case '+': // Look for ack 619 case '-': // Look for cancel 620 case '\x03': // ^C to halt target 621 end_idx = idx + 1; // The command is one byte long... 622 break; 623 624 case '$': 625 // Look for a standard gdb packet? 626 end_idx = data.find('#', idx + 1); 627 if (end_idx == std::string::npos || end_idx + 3 > data_size) 628 { 629 end_idx = std::string::npos; 630 } 631 else 632 { 633 // Add two for the checksum bytes and 1 to point to the 634 // byte just past the end of this packet 635 end_idx += 3; 636 } 637 break; 638 639 default: 640 break; 641 } 642 643 if (end_idx == std::string::npos) 644 { 645 // Not all data may be here for the packet yet, save it for 646 // next time through this function. 647 m_rx_partial_data += data.substr(idx); 648 //DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s saving data for later[%u, npos): '%s'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, idx, m_rx_partial_data.c_str()); 649 idx = end_idx; 650 } 651 else 652 if (idx < end_idx) 653 { 654 m_packets_recvd++; 655 // Hack to get rid of initial '+' ACK??? 656 if (m_packets_recvd == 1 && (end_idx == idx + 1) && data[idx] == '+') 657 { 658 //DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s throwing first ACK away....[%u, npos): '+'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, idx); 659 } 660 else 661 { 662 // We have a valid packet... 663 m_rx_packets.push_back(data.substr(idx, end_idx - idx)); 664 DNBLogThreadedIf (LOG_RNB_PACKETS, "getpkt: %s", m_rx_packets.back().c_str()); 665 } 666 idx = end_idx; 667 } 668 else 669 { 670 DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s tossing junk byte at %c",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, data[idx]); 671 idx = idx + 1; 672 } 673 } 674 } 675 676 if (!m_rx_packets.empty()) 677 { 678 // Let the main thread know we have received a packet 679 680 //DNBLogThreadedIf (LOG_RNB_EVENTS, "%8d RNBRemote::%s called events.SetEvent(RNBContext::event_read_packet_available)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 681 PThreadEvent& events = m_ctx.Events(); 682 events.SetEvents (RNBContext::event_read_packet_available); 683 } 684 } 685 686 rnb_err_t 687 RNBRemote::GetCommData () 688 { 689 // DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 690 std::string comm_data; 691 rnb_err_t err = m_comm.Read (comm_data); 692 if (err == rnb_success) 693 { 694 if (!comm_data.empty()) 695 CommDataReceived (comm_data); 696 } 697 return err; 698 } 699 700 void 701 RNBRemote::StartReadRemoteDataThread() 702 { 703 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 704 PThreadEvent& events = m_ctx.Events(); 705 if ((events.GetEventBits() & RNBContext::event_read_thread_running) == 0) 706 { 707 events.ResetEvents (RNBContext::event_read_thread_exiting); 708 int err = ::pthread_create (&m_rx_pthread, NULL, ThreadFunctionReadRemoteData, this); 709 if (err == 0) 710 { 711 // Our thread was successfully kicked off, wait for it to 712 // set the started event so we can safely continue 713 events.WaitForSetEvents (RNBContext::event_read_thread_running); 714 } 715 else 716 { 717 events.ResetEvents (RNBContext::event_read_thread_running); 718 events.SetEvents (RNBContext::event_read_thread_exiting); 719 } 720 } 721 } 722 723 void 724 RNBRemote::StopReadRemoteDataThread() 725 { 726 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__); 727 PThreadEvent& events = m_ctx.Events(); 728 if ((events.GetEventBits() & RNBContext::event_read_thread_running) == RNBContext::event_read_thread_running) 729 { 730 m_comm.Disconnect(true); 731 struct timespec timeout_abstime; 732 DNBTimer::OffsetTimeOfDay(&timeout_abstime, 2, 0); 733 734 // Wait for 2 seconds for the remote data thread to exit 735 if (events.WaitForSetEvents(RNBContext::event_read_thread_exiting, &timeout_abstime) == 0) 736 { 737 // Kill the remote data thread??? 738 } 739 } 740 } 741 742 743 void* 744 RNBRemote::ThreadFunctionReadRemoteData(void *arg) 745 { 746 // Keep a shared pointer reference so this doesn't go away on us before the thread is killed. 747 DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread starting...", __FUNCTION__, arg); 748 RNBRemoteSP remoteSP(g_remoteSP); 749 if (remoteSP.get() != NULL) 750 { 751 RNBRemote* remote = remoteSP.get(); 752 PThreadEvent& events = remote->Context().Events(); 753 events.SetEvents (RNBContext::event_read_thread_running); 754 // START: main receive remote command thread loop 755 bool done = false; 756 while (!done) 757 { 758 rnb_err_t err = remote->GetCommData(); 759 760 switch (err) 761 { 762 case rnb_success: 763 break; 764 765 default: 766 case rnb_err: 767 DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned error %u", err); 768 done = true; 769 break; 770 771 case rnb_not_connected: 772 DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned not connected..."); 773 done = true; 774 break; 775 } 776 } 777 // START: main receive remote command thread loop 778 events.ResetEvents (RNBContext::event_read_thread_running); 779 events.SetEvents (RNBContext::event_read_thread_exiting); 780 } 781 DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread exiting...", __FUNCTION__, arg); 782 return NULL; 783 } 784 785 786 // If we fail to get back a valid CPU type for the remote process, 787 // make a best guess for the CPU type based on the currently running 788 // debugserver binary -- the debugger may not handle the case of an 789 // un-specified process CPU type correctly. 790 791 static cpu_type_t 792 best_guess_cpu_type () 793 { 794 #if defined (__arm__) 795 return CPU_TYPE_ARM; 796 #elif defined (__i386__) || defined (__x86_64__) 797 if (sizeof (char*) == 8) 798 { 799 return CPU_TYPE_X86_64; 800 } 801 else 802 { 803 return CPU_TYPE_I386; 804 } 805 #endif 806 return 0; 807 } 808 809 810 /* Read the bytes in STR which are GDB Remote Protocol binary encoded bytes 811 (8-bit bytes). 812 This encoding uses 0x7d ('}') as an escape character for 0x7d ('}'), 813 0x23 ('#'), and 0x24 ('$'). 814 LEN is the number of bytes to be processed. If a character is escaped, 815 it is 2 characters for LEN. A LEN of -1 means encode-until-nul-byte 816 (end of string). */ 817 818 std::vector<uint8_t> 819 decode_binary_data (const char *str, size_t len) 820 { 821 std::vector<uint8_t> bytes; 822 if (len == 0) 823 { 824 return bytes; 825 } 826 if (len == -1) 827 len = strlen (str); 828 829 while (len--) 830 { 831 unsigned char c = *str; 832 if (c == 0x7d && len > 0) 833 { 834 len--; 835 str++; 836 c ^= 0x20; 837 } 838 bytes.push_back (c); 839 } 840 return bytes; 841 } 842 843 typedef struct register_map_entry 844 { 845 uint32_t gdb_regnum; // gdb register number 846 uint32_t offset; // Offset in bytes into the register context data with no padding between register values 847 DNBRegisterInfo nub_info; // debugnub register info 848 std::vector<uint32_t> value_regnums; 849 std::vector<uint32_t> invalidate_regnums; 850 } register_map_entry_t; 851 852 853 854 // If the notion of registers differs from what is handed out by the 855 // architecture, then flavors can be defined here. 856 857 static const uint32_t MAX_REGISTER_BYTE_SIZE = 16; 858 static const uint8_t k_zero_bytes[MAX_REGISTER_BYTE_SIZE] = {0}; 859 static std::vector<register_map_entry_t> g_dynamic_register_map; 860 static register_map_entry_t *g_reg_entries = NULL; 861 static size_t g_num_reg_entries = 0; 862 863 void 864 RNBRemote::Initialize() 865 { 866 DNBInitialize(); 867 } 868 869 870 bool 871 RNBRemote::InitializeRegisters (bool force) 872 { 873 pid_t pid = m_ctx.ProcessID(); 874 if (pid == INVALID_NUB_PROCESS) 875 return false; 876 877 DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface", __FUNCTION__); 878 // Discover the registers by querying the DNB interface and letting it 879 // state the registers that it would like to export. This allows the 880 // registers to be discovered using multiple qRegisterInfo calls to get 881 // all register information after the architecture for the process is 882 // determined. 883 if (force) 884 { 885 g_dynamic_register_map.clear(); 886 g_reg_entries = NULL; 887 g_num_reg_entries = 0; 888 } 889 890 if (g_dynamic_register_map.empty()) 891 { 892 nub_size_t num_reg_sets = 0; 893 const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets); 894 895 assert (num_reg_sets > 0 && reg_sets != NULL); 896 897 uint32_t regnum = 0; 898 uint32_t reg_data_offset = 0; 899 typedef std::map<std::string, uint32_t> NameToRegNum; 900 NameToRegNum name_to_regnum; 901 for (nub_size_t set = 0; set < num_reg_sets; ++set) 902 { 903 if (reg_sets[set].registers == NULL) 904 continue; 905 906 for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg) 907 { 908 register_map_entry_t reg_entry = { 909 regnum++, // register number starts at zero and goes up with no gaps 910 reg_data_offset, // Offset into register context data, no gaps between registers 911 reg_sets[set].registers[reg] // DNBRegisterInfo 912 }; 913 914 name_to_regnum[reg_entry.nub_info.name] = reg_entry.gdb_regnum; 915 916 if (reg_entry.nub_info.value_regs == NULL) 917 { 918 reg_data_offset += reg_entry.nub_info.size; 919 } 920 921 g_dynamic_register_map.push_back (reg_entry); 922 } 923 } 924 925 // Now we must find any regsiters whose values are in other registers and fix up 926 // the offsets since we removed all gaps... 927 for (auto ®_entry: g_dynamic_register_map) 928 { 929 if (reg_entry.nub_info.value_regs) 930 { 931 uint32_t new_offset = UINT32_MAX; 932 for (size_t i=0; reg_entry.nub_info.value_regs[i] != NULL; ++i) 933 { 934 const char *name = reg_entry.nub_info.value_regs[i]; 935 auto pos = name_to_regnum.find(name); 936 if (pos != name_to_regnum.end()) 937 { 938 regnum = pos->second; 939 reg_entry.value_regnums.push_back(regnum); 940 if (regnum < g_dynamic_register_map.size()) 941 { 942 // The offset for value_regs registers is the offset within the register with the lowest offset 943 const uint32_t reg_offset = g_dynamic_register_map[regnum].offset + reg_entry.nub_info.offset; 944 if (new_offset > reg_offset) 945 new_offset = reg_offset; 946 } 947 } 948 } 949 950 if (new_offset != UINT32_MAX) 951 { 952 reg_entry.offset = new_offset; 953 } 954 else 955 { 956 DNBLogThreaded("no offset was calculated entry for register %s", reg_entry.nub_info.name); 957 reg_entry.offset = UINT32_MAX; 958 } 959 } 960 961 if (reg_entry.nub_info.update_regs) 962 { 963 for (size_t i=0; reg_entry.nub_info.update_regs[i] != NULL; ++i) 964 { 965 const char *name = reg_entry.nub_info.update_regs[i]; 966 auto pos = name_to_regnum.find(name); 967 if (pos != name_to_regnum.end()) 968 { 969 regnum = pos->second; 970 reg_entry.invalidate_regnums.push_back(regnum); 971 } 972 } 973 } 974 } 975 976 977 // for (auto ®_entry: g_dynamic_register_map) 978 // { 979 // DNBLogThreaded("%4i: size = %3u, pseudo = %i, name = %s", 980 // reg_entry.offset, 981 // reg_entry.nub_info.size, 982 // reg_entry.nub_info.value_regs != NULL, 983 // reg_entry.nub_info.name); 984 // } 985 986 g_reg_entries = g_dynamic_register_map.data(); 987 g_num_reg_entries = g_dynamic_register_map.size(); 988 } 989 return true; 990 } 991 992 /* The inferior has stopped executing; send a packet 993 to gdb to let it know. */ 994 995 void 996 RNBRemote::NotifyThatProcessStopped (void) 997 { 998 RNBRemote::HandlePacket_last_signal (NULL); 999 return; 1000 } 1001 1002 1003 /* 'A arglen,argnum,arg,...' 1004 Update the inferior context CTX with the program name and arg 1005 list. 1006 The documentation for this packet is underwhelming but my best reading 1007 of this is that it is a series of (len, position #, arg)'s, one for 1008 each argument with "arg" hex encoded (two 0-9a-f chars?). 1009 Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either 1010 is sufficient to get around the "," position separator escape issue. 1011 1012 e.g. our best guess for a valid 'A' packet for "gdb -q a.out" is 1013 1014 6,0,676462,4,1,2d71,10,2,612e6f7574 1015 1016 Note that "argnum" and "arglen" are numbers in base 10. Again, that's 1017 not documented either way but I'm assuming it's so. */ 1018 1019 rnb_err_t 1020 RNBRemote::HandlePacket_A (const char *p) 1021 { 1022 if (p == NULL || *p == '\0') 1023 { 1024 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Null packet for 'A' pkt"); 1025 } 1026 p++; 1027 if (*p == '\0' || !isdigit (*p)) 1028 { 1029 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not specified on 'A' pkt"); 1030 } 1031 1032 /* I promise I don't modify it anywhere in this function. strtoul()'s 1033 2nd arg has to be non-const which makes it problematic to step 1034 through the string easily. */ 1035 char *buf = const_cast<char *>(p); 1036 1037 RNBContext& ctx = Context(); 1038 1039 while (*buf != '\0') 1040 { 1041 int arglen, argnum; 1042 std::string arg; 1043 char *c; 1044 1045 errno = 0; 1046 arglen = strtoul (buf, &c, 10); 1047 if (errno != 0 && arglen == 0) 1048 { 1049 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not a number on 'A' pkt"); 1050 } 1051 if (*c != ',') 1052 { 1053 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt"); 1054 } 1055 buf = c + 1; 1056 1057 errno = 0; 1058 argnum = strtoul (buf, &c, 10); 1059 if (errno != 0 && argnum == 0) 1060 { 1061 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "argnum not a number on 'A' pkt"); 1062 } 1063 if (*c != ',') 1064 { 1065 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt"); 1066 } 1067 buf = c + 1; 1068 1069 c = buf; 1070 buf = buf + arglen; 1071 while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0') 1072 { 1073 char smallbuf[3]; 1074 smallbuf[0] = *c; 1075 smallbuf[1] = *(c + 1); 1076 smallbuf[2] = '\0'; 1077 1078 errno = 0; 1079 int ch = strtoul (smallbuf, NULL, 16); 1080 if (errno != 0 && ch == 0) 1081 { 1082 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'A' pkt"); 1083 } 1084 1085 arg.push_back(ch); 1086 c += 2; 1087 } 1088 1089 ctx.PushArgument (arg.c_str()); 1090 if (*buf == ',') 1091 buf++; 1092 } 1093 SendPacket ("OK"); 1094 1095 return rnb_success; 1096 } 1097 1098 /* 'H c t' 1099 Set the thread for subsequent actions; 'c' for step/continue ops, 1100 'g' for other ops. -1 means all threads, 0 means any thread. */ 1101 1102 rnb_err_t 1103 RNBRemote::HandlePacket_H (const char *p) 1104 { 1105 p++; // skip 'H' 1106 if (*p != 'c' && *p != 'g') 1107 { 1108 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing 'c' or 'g' type in H packet"); 1109 } 1110 1111 if (!m_ctx.HasValidProcessID()) 1112 { 1113 // We allow gdb to connect to a server that hasn't started running 1114 // the target yet. gdb still wants to ask questions about it and 1115 // freaks out if it gets an error. So just return OK here. 1116 } 1117 1118 errno = 0; 1119 nub_thread_t tid = strtoul (p + 1, NULL, 16); 1120 if (errno != 0 && tid == 0) 1121 { 1122 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in H packet"); 1123 } 1124 if (*p == 'c') 1125 SetContinueThread (tid); 1126 if (*p == 'g') 1127 SetCurrentThread (tid); 1128 1129 return SendPacket ("OK"); 1130 } 1131 1132 1133 rnb_err_t 1134 RNBRemote::HandlePacket_qLaunchSuccess (const char *p) 1135 { 1136 if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Error() == 0) 1137 return SendPacket("OK"); 1138 std::ostringstream ret_str; 1139 std::string status_str; 1140 ret_str << "E" << m_ctx.LaunchStatusAsString(status_str); 1141 1142 return SendPacket (ret_str.str()); 1143 } 1144 1145 rnb_err_t 1146 RNBRemote::HandlePacket_qShlibInfoAddr (const char *p) 1147 { 1148 if (m_ctx.HasValidProcessID()) 1149 { 1150 nub_addr_t shlib_info_addr = DNBProcessGetSharedLibraryInfoAddress(m_ctx.ProcessID()); 1151 if (shlib_info_addr != INVALID_NUB_ADDRESS) 1152 { 1153 std::ostringstream ostrm; 1154 ostrm << RAW_HEXBASE << shlib_info_addr; 1155 return SendPacket (ostrm.str ()); 1156 } 1157 } 1158 return SendPacket ("E44"); 1159 } 1160 1161 rnb_err_t 1162 RNBRemote::HandlePacket_qStepPacketSupported (const char *p) 1163 { 1164 // Normally the "s" packet is mandatory, yet in gdb when using ARM, they 1165 // get around the need for this packet by implementing software single 1166 // stepping from gdb. Current versions of debugserver do support the "s" 1167 // packet, yet some older versions do not. We need a way to tell if this 1168 // packet is supported so we can disable software single stepping in gdb 1169 // for remote targets (so the "s" packet will get used). 1170 return SendPacket("OK"); 1171 } 1172 1173 rnb_err_t 1174 RNBRemote::HandlePacket_qSyncThreadStateSupported (const char *p) 1175 { 1176 // We support attachOrWait meaning attach if the process exists, otherwise wait to attach. 1177 return SendPacket("OK"); 1178 } 1179 1180 rnb_err_t 1181 RNBRemote::HandlePacket_qVAttachOrWaitSupported (const char *p) 1182 { 1183 // We support attachOrWait meaning attach if the process exists, otherwise wait to attach. 1184 return SendPacket("OK"); 1185 } 1186 1187 rnb_err_t 1188 RNBRemote::HandlePacket_qThreadStopInfo (const char *p) 1189 { 1190 p += strlen ("qThreadStopInfo"); 1191 nub_thread_t tid = strtoul(p, 0, 16); 1192 return SendStopReplyPacketForThread (tid); 1193 } 1194 1195 rnb_err_t 1196 RNBRemote::HandlePacket_qThreadInfo (const char *p) 1197 { 1198 // We allow gdb to connect to a server that hasn't started running 1199 // the target yet. gdb still wants to ask questions about it and 1200 // freaks out if it gets an error. So just return OK here. 1201 nub_process_t pid = m_ctx.ProcessID(); 1202 if (pid == INVALID_NUB_PROCESS) 1203 return SendPacket ("OK"); 1204 1205 // Only "qfThreadInfo" and "qsThreadInfo" get into this function so 1206 // we only need to check the second byte to tell which is which 1207 if (p[1] == 'f') 1208 { 1209 nub_size_t numthreads = DNBProcessGetNumThreads (pid); 1210 std::ostringstream ostrm; 1211 ostrm << "m"; 1212 bool first = true; 1213 for (nub_size_t i = 0; i < numthreads; ++i) 1214 { 1215 if (first) 1216 first = false; 1217 else 1218 ostrm << ","; 1219 nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i); 1220 ostrm << std::hex << th; 1221 } 1222 return SendPacket (ostrm.str ()); 1223 } 1224 else 1225 { 1226 return SendPacket ("l"); 1227 } 1228 } 1229 1230 rnb_err_t 1231 RNBRemote::HandlePacket_qThreadExtraInfo (const char *p) 1232 { 1233 // We allow gdb to connect to a server that hasn't started running 1234 // the target yet. gdb still wants to ask questions about it and 1235 // freaks out if it gets an error. So just return OK here. 1236 nub_process_t pid = m_ctx.ProcessID(); 1237 if (pid == INVALID_NUB_PROCESS) 1238 return SendPacket ("OK"); 1239 1240 /* This is supposed to return a string like 'Runnable' or 1241 'Blocked on Mutex'. 1242 The returned string is formatted like the "A" packet - a 1243 sequence of letters encoded in as 2-hex-chars-per-letter. */ 1244 p += strlen ("qThreadExtraInfo"); 1245 if (*p++ != ',') 1246 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Illformed qThreadExtraInfo packet"); 1247 errno = 0; 1248 nub_thread_t tid = strtoul (p, NULL, 16); 1249 if (errno != 0 && tid == 0) 1250 { 1251 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in qThreadExtraInfo packet"); 1252 } 1253 1254 const char * threadInfo = DNBThreadGetInfo(pid, tid); 1255 if (threadInfo != NULL && threadInfo[0]) 1256 { 1257 return SendHexEncodedBytePacket(NULL, threadInfo, strlen(threadInfo), NULL); 1258 } 1259 else 1260 { 1261 // "OK" == 4f6b 1262 // Return "OK" as a ASCII hex byte stream if things go wrong 1263 return SendPacket ("4f6b"); 1264 } 1265 1266 return SendPacket (""); 1267 } 1268 1269 1270 const char *k_space_delimiters = " \t"; 1271 static void 1272 skip_spaces (std::string &line) 1273 { 1274 if (!line.empty()) 1275 { 1276 size_t space_pos = line.find_first_not_of (k_space_delimiters); 1277 if (space_pos > 0) 1278 line.erase(0, space_pos); 1279 } 1280 } 1281 1282 static std::string 1283 get_identifier (std::string &line) 1284 { 1285 std::string word; 1286 skip_spaces (line); 1287 const size_t line_size = line.size(); 1288 size_t end_pos; 1289 for (end_pos = 0; end_pos < line_size; ++end_pos) 1290 { 1291 if (end_pos == 0) 1292 { 1293 if (isalpha(line[end_pos]) || line[end_pos] == '_') 1294 continue; 1295 } 1296 else if (isalnum(line[end_pos]) || line[end_pos] == '_') 1297 continue; 1298 break; 1299 } 1300 word.assign (line, 0, end_pos); 1301 line.erase(0, end_pos); 1302 return word; 1303 } 1304 1305 static std::string 1306 get_operator (std::string &line) 1307 { 1308 std::string op; 1309 skip_spaces (line); 1310 if (!line.empty()) 1311 { 1312 if (line[0] == '=') 1313 { 1314 op = '='; 1315 line.erase(0,1); 1316 } 1317 } 1318 return op; 1319 } 1320 1321 static std::string 1322 get_value (std::string &line) 1323 { 1324 std::string value; 1325 skip_spaces (line); 1326 if (!line.empty()) 1327 { 1328 value.swap(line); 1329 } 1330 return value; 1331 } 1332 1333 extern void FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args); 1334 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); 1335 1336 rnb_err_t 1337 RNBRemote::HandlePacket_qRcmd (const char *p) 1338 { 1339 const char *c = p + strlen("qRcmd,"); 1340 std::string line; 1341 while (c[0] && c[1]) 1342 { 1343 char smallbuf[3] = { c[0], c[1], '\0' }; 1344 errno = 0; 1345 int ch = strtoul (smallbuf, NULL, 16); 1346 if (errno != 0 && ch == 0) 1347 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in payload of qRcmd packet"); 1348 line.push_back(ch); 1349 c += 2; 1350 } 1351 if (*c == '\0') 1352 { 1353 std::string command = get_identifier(line); 1354 if (command.compare("set") == 0) 1355 { 1356 std::string variable = get_identifier (line); 1357 std::string op = get_operator (line); 1358 std::string value = get_value (line); 1359 if (variable.compare("logfile") == 0) 1360 { 1361 FILE *log_file = fopen(value.c_str(), "w"); 1362 if (log_file) 1363 { 1364 DNBLogSetLogCallback(FileLogCallback, log_file); 1365 return SendPacket ("OK"); 1366 } 1367 return SendPacket ("E71"); 1368 } 1369 else if (variable.compare("logmask") == 0) 1370 { 1371 char *end; 1372 errno = 0; 1373 uint32_t logmask = strtoul (value.c_str(), &end, 0); 1374 if (errno == 0 && end && *end == '\0') 1375 { 1376 DNBLogSetLogMask (logmask); 1377 if (!DNBLogGetLogCallback()) 1378 DNBLogSetLogCallback(ASLLogCallback, NULL); 1379 return SendPacket ("OK"); 1380 } 1381 errno = 0; 1382 logmask = strtoul (value.c_str(), &end, 16); 1383 if (errno == 0 && end && *end == '\0') 1384 { 1385 DNBLogSetLogMask (logmask); 1386 return SendPacket ("OK"); 1387 } 1388 return SendPacket ("E72"); 1389 } 1390 return SendPacket ("E70"); 1391 } 1392 return SendPacket ("E69"); 1393 } 1394 return SendPacket ("E73"); 1395 } 1396 1397 rnb_err_t 1398 RNBRemote::HandlePacket_qC (const char *p) 1399 { 1400 nub_process_t pid; 1401 std::ostringstream rep; 1402 // If we haven't run the process yet, we tell the debugger the 1403 // pid is 0. That way it can know to tell use to run later on. 1404 if (m_ctx.HasValidProcessID()) 1405 pid = m_ctx.ProcessID(); 1406 else 1407 pid = 0; 1408 rep << "QC" << std::hex << pid; 1409 return SendPacket (rep.str()); 1410 } 1411 1412 rnb_err_t 1413 RNBRemote::HandlePacket_qGetPid (const char *p) 1414 { 1415 nub_process_t pid; 1416 std::ostringstream rep; 1417 // If we haven't run the process yet, we tell the debugger the 1418 // pid is 0. That way it can know to tell use to run later on. 1419 if (m_ctx.HasValidProcessID()) 1420 pid = m_ctx.ProcessID(); 1421 else 1422 pid = 0; 1423 rep << std::hex << pid; 1424 return SendPacket (rep.str()); 1425 } 1426 1427 rnb_err_t 1428 RNBRemote::HandlePacket_qRegisterInfo (const char *p) 1429 { 1430 if (g_num_reg_entries == 0) 1431 InitializeRegisters (); 1432 1433 p += strlen ("qRegisterInfo"); 1434 1435 nub_size_t num_reg_sets = 0; 1436 const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo (&num_reg_sets); 1437 uint32_t reg_num = strtoul(p, 0, 16); 1438 1439 if (reg_num < g_num_reg_entries) 1440 { 1441 const register_map_entry_t *reg_entry = &g_reg_entries[reg_num]; 1442 std::ostringstream ostrm; 1443 if (reg_entry->nub_info.name) 1444 ostrm << "name:" << reg_entry->nub_info.name << ';'; 1445 if (reg_entry->nub_info.alt) 1446 ostrm << "alt-name:" << reg_entry->nub_info.alt << ';'; 1447 1448 ostrm << "bitsize:" << std::dec << reg_entry->nub_info.size * 8 << ';'; 1449 ostrm << "offset:" << std::dec << reg_entry->offset << ';'; 1450 1451 switch (reg_entry->nub_info.type) 1452 { 1453 case Uint: ostrm << "encoding:uint;"; break; 1454 case Sint: ostrm << "encoding:sint;"; break; 1455 case IEEE754: ostrm << "encoding:ieee754;"; break; 1456 case Vector: ostrm << "encoding:vector;"; break; 1457 } 1458 1459 switch (reg_entry->nub_info.format) 1460 { 1461 case Binary: ostrm << "format:binary;"; break; 1462 case Decimal: ostrm << "format:decimal;"; break; 1463 case Hex: ostrm << "format:hex;"; break; 1464 case Float: ostrm << "format:float;"; break; 1465 case VectorOfSInt8: ostrm << "format:vector-sint8;"; break; 1466 case VectorOfUInt8: ostrm << "format:vector-uint8;"; break; 1467 case VectorOfSInt16: ostrm << "format:vector-sint16;"; break; 1468 case VectorOfUInt16: ostrm << "format:vector-uint16;"; break; 1469 case VectorOfSInt32: ostrm << "format:vector-sint32;"; break; 1470 case VectorOfUInt32: ostrm << "format:vector-uint32;"; break; 1471 case VectorOfFloat32: ostrm << "format:vector-float32;"; break; 1472 case VectorOfUInt128: ostrm << "format:vector-uint128;"; break; 1473 }; 1474 1475 if (reg_set_info && reg_entry->nub_info.set < num_reg_sets) 1476 ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';'; 1477 1478 if (reg_entry->nub_info.reg_gcc != INVALID_NUB_REGNUM) 1479 ostrm << "gcc:" << std::dec << reg_entry->nub_info.reg_gcc << ';'; 1480 1481 if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM) 1482 ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';'; 1483 1484 switch (reg_entry->nub_info.reg_generic) 1485 { 1486 case GENERIC_REGNUM_FP: ostrm << "generic:fp;"; break; 1487 case GENERIC_REGNUM_PC: ostrm << "generic:pc;"; break; 1488 case GENERIC_REGNUM_SP: ostrm << "generic:sp;"; break; 1489 case GENERIC_REGNUM_RA: ostrm << "generic:ra;"; break; 1490 case GENERIC_REGNUM_FLAGS: ostrm << "generic:flags;"; break; 1491 case GENERIC_REGNUM_ARG1: ostrm << "generic:arg1;"; break; 1492 case GENERIC_REGNUM_ARG2: ostrm << "generic:arg2;"; break; 1493 case GENERIC_REGNUM_ARG3: ostrm << "generic:arg3;"; break; 1494 case GENERIC_REGNUM_ARG4: ostrm << "generic:arg4;"; break; 1495 case GENERIC_REGNUM_ARG5: ostrm << "generic:arg5;"; break; 1496 case GENERIC_REGNUM_ARG6: ostrm << "generic:arg6;"; break; 1497 case GENERIC_REGNUM_ARG7: ostrm << "generic:arg7;"; break; 1498 case GENERIC_REGNUM_ARG8: ostrm << "generic:arg8;"; break; 1499 default: break; 1500 } 1501 1502 if (!reg_entry->value_regnums.empty()) 1503 { 1504 ostrm << "container-regs:"; 1505 for (size_t i=0, n=reg_entry->value_regnums.size(); i < n; ++i) 1506 { 1507 if (i > 0) 1508 ostrm << ','; 1509 ostrm << RAW_HEXBASE << reg_entry->value_regnums[i]; 1510 } 1511 ostrm << ';'; 1512 } 1513 1514 if (!reg_entry->invalidate_regnums.empty()) 1515 { 1516 ostrm << "invalidate-regs:"; 1517 for (size_t i=0, n=reg_entry->invalidate_regnums.size(); i < n; ++i) 1518 { 1519 if (i > 0) 1520 ostrm << ','; 1521 ostrm << RAW_HEXBASE << reg_entry->invalidate_regnums[i]; 1522 } 1523 ostrm << ';'; 1524 } 1525 1526 return SendPacket (ostrm.str ()); 1527 } 1528 return SendPacket ("E45"); 1529 } 1530 1531 1532 /* This expects a packet formatted like 1533 1534 QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE; 1535 1536 with the "QSetLogging:" already removed from the start. Maybe in the 1537 future this packet will include other keyvalue pairs like 1538 1539 QSetLogging:bitmask=LOG_ALL;mode=asl; 1540 */ 1541 1542 rnb_err_t 1543 set_logging (const char *p) 1544 { 1545 int bitmask = 0; 1546 while (p && *p != '\0') 1547 { 1548 if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0) 1549 { 1550 p += sizeof ("bitmask=") - 1; 1551 while (p && *p != '\0' && *p != ';') 1552 { 1553 if (*p == '|') 1554 p++; 1555 1556 // to regenerate the LOG_ entries (not including the LOG_RNB entries) 1557 // $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 'LOG_HI|LOG_LO' | awk '{print $2}'` 1558 // do 1559 // echo " else if (strncmp (p, \"$logname\", sizeof (\"$logname\") - 1) == 0)" 1560 // echo " {" 1561 // echo " p += sizeof (\"$logname\") - 1;" 1562 // echo " bitmask |= $logname;" 1563 // echo " }" 1564 // done 1565 if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0) 1566 { 1567 p += sizeof ("LOG_VERBOSE") - 1; 1568 bitmask |= LOG_VERBOSE; 1569 } 1570 else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0) 1571 { 1572 p += sizeof ("LOG_PROCESS") - 1; 1573 bitmask |= LOG_PROCESS; 1574 } 1575 else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0) 1576 { 1577 p += sizeof ("LOG_THREAD") - 1; 1578 bitmask |= LOG_THREAD; 1579 } 1580 else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0) 1581 { 1582 p += sizeof ("LOG_EXCEPTIONS") - 1; 1583 bitmask |= LOG_EXCEPTIONS; 1584 } 1585 else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0) 1586 { 1587 p += sizeof ("LOG_SHLIB") - 1; 1588 bitmask |= LOG_SHLIB; 1589 } 1590 else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0) 1591 { 1592 p += sizeof ("LOG_MEMORY") - 1; 1593 bitmask |= LOG_MEMORY; 1594 } 1595 else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0) 1596 { 1597 p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1; 1598 bitmask |= LOG_MEMORY_DATA_SHORT; 1599 } 1600 else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0) 1601 { 1602 p += sizeof ("LOG_MEMORY_DATA_LONG") - 1; 1603 bitmask |= LOG_MEMORY_DATA_LONG; 1604 } 1605 else if (strncmp (p, "LOG_MEMORY_PROTECTIONS", sizeof ("LOG_MEMORY_PROTECTIONS") - 1) == 0) 1606 { 1607 p += sizeof ("LOG_MEMORY_PROTECTIONS") - 1; 1608 bitmask |= LOG_MEMORY_PROTECTIONS; 1609 } 1610 else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0) 1611 { 1612 p += sizeof ("LOG_BREAKPOINTS") - 1; 1613 bitmask |= LOG_BREAKPOINTS; 1614 } 1615 else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0) 1616 { 1617 p += sizeof ("LOG_EVENTS") - 1; 1618 bitmask |= LOG_EVENTS; 1619 } 1620 else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0) 1621 { 1622 p += sizeof ("LOG_WATCHPOINTS") - 1; 1623 bitmask |= LOG_WATCHPOINTS; 1624 } 1625 else if (strncmp (p, "LOG_STEP", sizeof ("LOG_STEP") - 1) == 0) 1626 { 1627 p += sizeof ("LOG_STEP") - 1; 1628 bitmask |= LOG_STEP; 1629 } 1630 else if (strncmp (p, "LOG_TASK", sizeof ("LOG_TASK") - 1) == 0) 1631 { 1632 p += sizeof ("LOG_TASK") - 1; 1633 bitmask |= LOG_TASK; 1634 } 1635 else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0) 1636 { 1637 p += sizeof ("LOG_ALL") - 1; 1638 bitmask |= LOG_ALL; 1639 } 1640 else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0) 1641 { 1642 p += sizeof ("LOG_DEFAULT") - 1; 1643 bitmask |= LOG_DEFAULT; 1644 } 1645 // end of auto-generated entries 1646 1647 else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0) 1648 { 1649 p += sizeof ("LOG_NONE") - 1; 1650 bitmask = 0; 1651 } 1652 else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0) 1653 { 1654 p += sizeof ("LOG_RNB_MINIMAL") - 1; 1655 bitmask |= LOG_RNB_MINIMAL; 1656 } 1657 else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0) 1658 { 1659 p += sizeof ("LOG_RNB_MEDIUM") - 1; 1660 bitmask |= LOG_RNB_MEDIUM; 1661 } 1662 else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0) 1663 { 1664 p += sizeof ("LOG_RNB_MAX") - 1; 1665 bitmask |= LOG_RNB_MAX; 1666 } 1667 else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0) 1668 { 1669 p += sizeof ("LOG_RNB_COMM") - 1; 1670 bitmask |= LOG_RNB_COMM; 1671 } 1672 else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0) 1673 { 1674 p += sizeof ("LOG_RNB_REMOTE") - 1; 1675 bitmask |= LOG_RNB_REMOTE; 1676 } 1677 else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0) 1678 { 1679 p += sizeof ("LOG_RNB_EVENTS") - 1; 1680 bitmask |= LOG_RNB_EVENTS; 1681 } 1682 else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0) 1683 { 1684 p += sizeof ("LOG_RNB_PROC") - 1; 1685 bitmask |= LOG_RNB_PROC; 1686 } 1687 else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0) 1688 { 1689 p += sizeof ("LOG_RNB_PACKETS") - 1; 1690 bitmask |= LOG_RNB_PACKETS; 1691 } 1692 else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0) 1693 { 1694 p += sizeof ("LOG_RNB_ALL") - 1; 1695 bitmask |= LOG_RNB_ALL; 1696 } 1697 else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0) 1698 { 1699 p += sizeof ("LOG_RNB_DEFAULT") - 1; 1700 bitmask |= LOG_RNB_DEFAULT; 1701 } 1702 else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0) 1703 { 1704 p += sizeof ("LOG_RNB_NONE") - 1; 1705 bitmask = 0; 1706 } 1707 else 1708 { 1709 /* Unrecognized logging bit; ignore it. */ 1710 const char *c = strchr (p, '|'); 1711 if (c) 1712 { 1713 p = c; 1714 } 1715 else 1716 { 1717 c = strchr (p, ';'); 1718 if (c) 1719 { 1720 p = c; 1721 } 1722 else 1723 { 1724 // Improperly terminated word; just go to end of str 1725 p = strchr (p, '\0'); 1726 } 1727 } 1728 } 1729 } 1730 // Did we get a properly formatted logging bitmask? 1731 if (p && *p == ';') 1732 { 1733 // Enable DNB logging 1734 DNBLogSetLogCallback(ASLLogCallback, NULL); 1735 DNBLogSetLogMask (bitmask); 1736 p++; 1737 } 1738 } 1739 // We're not going to support logging to a file for now. All logging 1740 // goes through ASL. 1741 #if 0 1742 else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0) 1743 { 1744 p += sizeof ("mode=") - 1; 1745 if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0) 1746 { 1747 DNBLogToASL (); 1748 p += sizeof ("asl;") - 1; 1749 } 1750 else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0) 1751 { 1752 DNBLogToFile (); 1753 p += sizeof ("file;") - 1; 1754 } 1755 else 1756 { 1757 // Ignore unknown argument 1758 const char *c = strchr (p, ';'); 1759 if (c) 1760 p = c + 1; 1761 else 1762 p = strchr (p, '\0'); 1763 } 1764 } 1765 else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0) 1766 { 1767 p += sizeof ("filename=") - 1; 1768 const char *c = strchr (p, ';'); 1769 if (c == NULL) 1770 { 1771 c = strchr (p, '\0'); 1772 continue; 1773 } 1774 char *fn = (char *) alloca (c - p + 1); 1775 strncpy (fn, p, c - p); 1776 fn[c - p] = '\0'; 1777 1778 // A file name of "asl" is special and is another way to indicate 1779 // that logging should be done via ASL, not by file. 1780 if (strcmp (fn, "asl") == 0) 1781 { 1782 DNBLogToASL (); 1783 } 1784 else 1785 { 1786 FILE *f = fopen (fn, "w"); 1787 if (f) 1788 { 1789 DNBLogSetLogFile (f); 1790 DNBEnableLogging (f, DNBLogGetLogMask ()); 1791 DNBLogToFile (); 1792 } 1793 } 1794 p = c + 1; 1795 } 1796 #endif /* #if 0 to enforce ASL logging only. */ 1797 else 1798 { 1799 // Ignore unknown argument 1800 const char *c = strchr (p, ';'); 1801 if (c) 1802 p = c + 1; 1803 else 1804 p = strchr (p, '\0'); 1805 } 1806 } 1807 1808 return rnb_success; 1809 } 1810 1811 rnb_err_t 1812 RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p) 1813 { 1814 m_thread_suffix_supported = true; 1815 return SendPacket ("OK"); 1816 } 1817 1818 rnb_err_t 1819 RNBRemote::HandlePacket_QStartNoAckMode (const char *p) 1820 { 1821 // Send the OK packet first so the correct checksum is appended... 1822 rnb_err_t result = SendPacket ("OK"); 1823 m_noack_mode = true; 1824 return result; 1825 } 1826 1827 1828 rnb_err_t 1829 RNBRemote::HandlePacket_QSetLogging (const char *p) 1830 { 1831 p += sizeof ("QSetLogging:") - 1; 1832 rnb_err_t result = set_logging (p); 1833 if (result == rnb_success) 1834 return SendPacket ("OK"); 1835 else 1836 return SendPacket ("E35"); 1837 } 1838 1839 rnb_err_t 1840 RNBRemote::HandlePacket_QSetDisableASLR (const char *p) 1841 { 1842 extern int g_disable_aslr; 1843 p += sizeof ("QSetDisableASLR:") - 1; 1844 switch (*p) 1845 { 1846 case '0': g_disable_aslr = 0; break; 1847 case '1': g_disable_aslr = 1; break; 1848 default: 1849 return SendPacket ("E56"); 1850 } 1851 return SendPacket ("OK"); 1852 } 1853 1854 rnb_err_t 1855 RNBRemote::HandlePacket_QSetSTDIO (const char *p) 1856 { 1857 // Only set stdin/out/err if we don't already have a process 1858 if (!m_ctx.HasValidProcessID()) 1859 { 1860 bool success = false; 1861 // Check the seventh character since the packet will be one of: 1862 // QSetSTDIN 1863 // QSetSTDOUT 1864 // QSetSTDERR 1865 StringExtractor packet(p); 1866 packet.SetFilePos (7); 1867 char ch = packet.GetChar(); 1868 while (packet.GetChar() != ':') 1869 /* Do nothing. */; 1870 1871 switch (ch) 1872 { 1873 case 'I': // STDIN 1874 packet.GetHexByteString (m_ctx.GetSTDIN()); 1875 success = !m_ctx.GetSTDIN().empty(); 1876 break; 1877 1878 case 'O': // STDOUT 1879 packet.GetHexByteString (m_ctx.GetSTDOUT()); 1880 success = !m_ctx.GetSTDOUT().empty(); 1881 break; 1882 1883 case 'E': // STDERR 1884 packet.GetHexByteString (m_ctx.GetSTDERR()); 1885 success = !m_ctx.GetSTDERR().empty(); 1886 break; 1887 1888 default: 1889 break; 1890 } 1891 if (success) 1892 return SendPacket ("OK"); 1893 return SendPacket ("E57"); 1894 } 1895 return SendPacket ("E58"); 1896 } 1897 1898 rnb_err_t 1899 RNBRemote::HandlePacket_QSetWorkingDir (const char *p) 1900 { 1901 // Only set the working directory if we don't already have a process 1902 if (!m_ctx.HasValidProcessID()) 1903 { 1904 StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1); 1905 if (packet.GetHexByteString (m_ctx.GetWorkingDir())) 1906 { 1907 struct stat working_dir_stat; 1908 if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1) 1909 { 1910 m_ctx.GetWorkingDir().clear(); 1911 return SendPacket ("E61"); // Working directory doesn't exist... 1912 } 1913 else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR) 1914 { 1915 return SendPacket ("OK"); 1916 } 1917 else 1918 { 1919 m_ctx.GetWorkingDir().clear(); 1920 return SendPacket ("E62"); // Working directory isn't a directory... 1921 } 1922 } 1923 return SendPacket ("E59"); // Invalid path 1924 } 1925 return SendPacket ("E60"); // Already had a process, too late to set working dir 1926 } 1927 1928 rnb_err_t 1929 RNBRemote::HandlePacket_QSyncThreadState (const char *p) 1930 { 1931 if (!m_ctx.HasValidProcessID()) 1932 { 1933 // We allow gdb to connect to a server that hasn't started running 1934 // the target yet. gdb still wants to ask questions about it and 1935 // freaks out if it gets an error. So just return OK here. 1936 return SendPacket ("OK"); 1937 } 1938 1939 errno = 0; 1940 p += strlen("QSyncThreadState:"); 1941 nub_thread_t tid = strtoul (p, NULL, 16); 1942 if (errno != 0 && tid == 0) 1943 { 1944 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in QSyncThreadState packet"); 1945 } 1946 if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid)) 1947 return SendPacket("OK"); 1948 else 1949 return SendPacket ("E61"); 1950 } 1951 1952 rnb_err_t 1953 RNBRemote::HandlePacket_QListThreadsInStopReply (const char *p) 1954 { 1955 // If this packet is received, it allows us to send an extra key/value 1956 // pair in the stop reply packets where we will list all of the thread IDs 1957 // separated by commas: 1958 // 1959 // "threads:10a,10b,10c;" 1960 // 1961 // This will get included in the stop reply packet as something like: 1962 // 1963 // "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;" 1964 // 1965 // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and 1966 // speed things up a bit. 1967 // 1968 // Send the OK packet first so the correct checksum is appended... 1969 rnb_err_t result = SendPacket ("OK"); 1970 m_list_threads_in_stop_reply = true; 1971 return result; 1972 } 1973 1974 1975 rnb_err_t 1976 RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p) 1977 { 1978 /* The number of characters in a packet payload that gdb is 1979 prepared to accept. The packet-start char, packet-end char, 1980 2 checksum chars and terminating null character are not included 1981 in this size. */ 1982 p += sizeof ("QSetMaxPayloadSize:") - 1; 1983 errno = 0; 1984 uint32_t size = strtoul (p, NULL, 16); 1985 if (errno != 0 && size == 0) 1986 { 1987 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet"); 1988 } 1989 m_max_payload_size = size; 1990 return SendPacket ("OK"); 1991 } 1992 1993 rnb_err_t 1994 RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p) 1995 { 1996 /* This tells us the largest packet that gdb can handle. 1997 i.e. the size of gdb's packet-reading buffer. 1998 QSetMaxPayloadSize is preferred because it is less ambiguous. */ 1999 p += sizeof ("QSetMaxPacketSize:") - 1; 2000 errno = 0; 2001 uint32_t size = strtoul (p, NULL, 16); 2002 if (errno != 0 && size == 0) 2003 { 2004 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet"); 2005 } 2006 m_max_payload_size = size - 5; 2007 return SendPacket ("OK"); 2008 } 2009 2010 2011 2012 2013 rnb_err_t 2014 RNBRemote::HandlePacket_QEnvironment (const char *p) 2015 { 2016 /* This sets the environment for the target program. The packet is of the form: 2017 2018 QEnvironment:VARIABLE=VALUE 2019 2020 */ 2021 2022 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"", 2023 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2024 2025 p += sizeof ("QEnvironment:") - 1; 2026 RNBContext& ctx = Context(); 2027 2028 ctx.PushEnvironment (p); 2029 return SendPacket ("OK"); 2030 } 2031 2032 rnb_err_t 2033 RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p) 2034 { 2035 /* This sets the environment for the target program. The packet is of the form: 2036 2037 QEnvironmentHexEncoded:VARIABLE=VALUE 2038 2039 The VARIABLE=VALUE part is sent hex-encoded so chracters like '#' with special 2040 meaning in the remote protocol won't break it. 2041 */ 2042 2043 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"", 2044 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2045 2046 p += sizeof ("QEnvironmentHexEncoded:") - 1; 2047 2048 std::string arg; 2049 const char *c; 2050 c = p; 2051 while (*c != '\0') 2052 { 2053 if (*(c + 1) == '\0') 2054 { 2055 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2056 } 2057 char smallbuf[3]; 2058 smallbuf[0] = *c; 2059 smallbuf[1] = *(c + 1); 2060 smallbuf[2] = '\0'; 2061 errno = 0; 2062 int ch = strtoul (smallbuf, NULL, 16); 2063 if (errno != 0 && ch == 0) 2064 { 2065 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2066 } 2067 arg.push_back(ch); 2068 c += 2; 2069 } 2070 2071 RNBContext& ctx = Context(); 2072 if (arg.length() > 0) 2073 ctx.PushEnvironment (arg.c_str()); 2074 2075 return SendPacket ("OK"); 2076 } 2077 2078 2079 rnb_err_t 2080 RNBRemote::HandlePacket_QLaunchArch (const char *p) 2081 { 2082 p += sizeof ("QLaunchArch:") - 1; 2083 if (DNBSetArchitecture(p)) 2084 return SendPacket ("OK"); 2085 return SendPacket ("E63"); 2086 } 2087 2088 void 2089 append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap) 2090 { 2091 int i; 2092 if (swap) 2093 { 2094 for (i = buf_size-1; i >= 0; i--) 2095 ostrm << RAWHEX8(buf[i]); 2096 } 2097 else 2098 { 2099 for (i = 0; i < buf_size; i++) 2100 ostrm << RAWHEX8(buf[i]); 2101 } 2102 } 2103 2104 2105 void 2106 register_value_in_hex_fixed_width (std::ostream& ostrm, 2107 nub_process_t pid, 2108 nub_thread_t tid, 2109 const register_map_entry_t* reg, 2110 const DNBRegisterValue *reg_value_ptr) 2111 { 2112 if (reg != NULL) 2113 { 2114 DNBRegisterValue reg_value; 2115 if (reg_value_ptr == NULL) 2116 { 2117 if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, ®_value)) 2118 reg_value_ptr = ®_value; 2119 } 2120 2121 if (reg_value_ptr) 2122 { 2123 append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size, false); 2124 } 2125 else 2126 { 2127 // If we fail to read a regiser value, check if it has a default 2128 // fail value. If it does, return this instead in case some of 2129 // the registers are not available on the current system. 2130 if (reg->nub_info.size > 0) 2131 { 2132 std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0'); 2133 append_hex_value (ostrm, zeros.data(), zeros.size(), false); 2134 } 2135 } 2136 } 2137 } 2138 2139 2140 void 2141 gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm, 2142 nub_process_t pid, 2143 nub_thread_t tid, 2144 const register_map_entry_t* reg, 2145 const DNBRegisterValue *reg_value_ptr) 2146 { 2147 // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX 2148 // gdb register number, and VVVVVVVV is the correct number of hex bytes 2149 // as ASCII for the register value. 2150 if (reg != NULL) 2151 { 2152 ostrm << RAWHEX8(reg->gdb_regnum) << ':'; 2153 register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr); 2154 ostrm << ';'; 2155 } 2156 } 2157 2158 rnb_err_t 2159 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) 2160 { 2161 const nub_process_t pid = m_ctx.ProcessID(); 2162 if (pid == INVALID_NUB_PROCESS) 2163 return SendPacket("E50"); 2164 2165 struct DNBThreadStopInfo tid_stop_info; 2166 2167 /* Fill the remaining space in this packet with as many registers 2168 as we can stuff in there. */ 2169 2170 if (DNBThreadGetStopReason (pid, tid, &tid_stop_info)) 2171 { 2172 const bool did_exec = tid_stop_info.reason == eStopTypeExec; 2173 if (did_exec) 2174 RNBRemote::InitializeRegisters(true); 2175 2176 std::ostringstream ostrm; 2177 // Output the T packet with the thread 2178 ostrm << 'T'; 2179 int signum = tid_stop_info.details.signal.signo; 2180 DNBLogThreadedIf (LOG_RNB_PROC, "%8d %s got signal signo = %u, exc_type = %u", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, signum, tid_stop_info.details.exception.type); 2181 2182 // Translate any mach exceptions to gdb versions, unless they are 2183 // common exceptions like a breakpoint or a soft signal. 2184 switch (tid_stop_info.details.exception.type) 2185 { 2186 default: signum = 0; break; 2187 case EXC_BREAKPOINT: signum = SIGTRAP; break; 2188 case EXC_BAD_ACCESS: signum = TARGET_EXC_BAD_ACCESS; break; 2189 case EXC_BAD_INSTRUCTION: signum = TARGET_EXC_BAD_INSTRUCTION; break; 2190 case EXC_ARITHMETIC: signum = TARGET_EXC_ARITHMETIC; break; 2191 case EXC_EMULATION: signum = TARGET_EXC_EMULATION; break; 2192 case EXC_SOFTWARE: 2193 if (tid_stop_info.details.exception.data_count == 2 && 2194 tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL) 2195 signum = tid_stop_info.details.exception.data[1]; 2196 else 2197 signum = TARGET_EXC_SOFTWARE; 2198 break; 2199 } 2200 2201 ostrm << RAWHEX8(signum & 0xff); 2202 2203 ostrm << std::hex << "thread:" << tid << ';'; 2204 2205 const char *thread_name = DNBThreadGetName (pid, tid); 2206 if (thread_name && thread_name[0]) 2207 { 2208 size_t thread_name_len = strlen(thread_name); 2209 2210 if (::strcspn (thread_name, "$#+-;:") == thread_name_len) 2211 ostrm << std::hex << "name:" << thread_name << ';'; 2212 else 2213 { 2214 // the thread name contains special chars, send as hex bytes 2215 ostrm << std::hex << "hexname:"; 2216 uint8_t *u_thread_name = (uint8_t *)thread_name; 2217 for (int i = 0; i < thread_name_len; i++) 2218 ostrm << RAWHEX8(u_thread_name[i]); 2219 ostrm << ';'; 2220 } 2221 } 2222 2223 thread_identifier_info_data_t thread_ident_info; 2224 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 2225 { 2226 if (thread_ident_info.dispatch_qaddr != 0) 2227 ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';'; 2228 } 2229 2230 // If a 'QListThreadsInStopReply' was sent to enable this feature, we 2231 // will send all thread IDs back in the "threads" key whose value is 2232 // a listc of hex thread IDs separated by commas: 2233 // "threads:10a,10b,10c;" 2234 // This will save the debugger from having to send a pair of qfThreadInfo 2235 // and qsThreadInfo packets, but it also might take a lot of room in the 2236 // stop reply packet, so it must be enabled only on systems where there 2237 // are no limits on packet lengths. 2238 2239 if (m_list_threads_in_stop_reply) 2240 { 2241 const nub_size_t numthreads = DNBProcessGetNumThreads (pid); 2242 if (numthreads > 0) 2243 { 2244 ostrm << std::hex << "threads:"; 2245 for (nub_size_t i = 0; i < numthreads; ++i) 2246 { 2247 nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i); 2248 if (i > 0) 2249 ostrm << ','; 2250 ostrm << std::hex << th; 2251 } 2252 ostrm << ';'; 2253 } 2254 } 2255 2256 if (g_num_reg_entries == 0) 2257 InitializeRegisters (); 2258 2259 if (g_reg_entries != NULL) 2260 { 2261 DNBRegisterValue reg_value; 2262 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2263 { 2264 // Expedite all registers in the first register set that aren't 2265 // contained in other registers 2266 if (g_reg_entries[reg].nub_info.set == 1 && 2267 g_reg_entries[reg].nub_info.value_regs == NULL) 2268 { 2269 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 2270 continue; 2271 2272 gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], ®_value); 2273 } 2274 } 2275 } 2276 2277 if (did_exec) 2278 { 2279 ostrm << "reason:exec;"; 2280 } 2281 else if (tid_stop_info.details.exception.type) 2282 { 2283 ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";"; 2284 ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";"; 2285 for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i) 2286 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";"; 2287 } 2288 return SendPacket (ostrm.str ()); 2289 } 2290 return SendPacket("E51"); 2291 } 2292 2293 /* '?' 2294 The stop reply packet - tell gdb what the status of the inferior is. 2295 Often called the questionmark_packet. */ 2296 2297 rnb_err_t 2298 RNBRemote::HandlePacket_last_signal (const char *unused) 2299 { 2300 if (!m_ctx.HasValidProcessID()) 2301 { 2302 // Inferior is not yet specified/running 2303 return SendPacket ("E02"); 2304 } 2305 2306 nub_process_t pid = m_ctx.ProcessID(); 2307 nub_state_t pid_state = DNBProcessGetState (pid); 2308 2309 switch (pid_state) 2310 { 2311 case eStateAttaching: 2312 case eStateLaunching: 2313 case eStateRunning: 2314 case eStateStepping: 2315 case eStateDetached: 2316 return rnb_success; // Ignore 2317 2318 case eStateSuspended: 2319 case eStateStopped: 2320 case eStateCrashed: 2321 { 2322 nub_thread_t tid = DNBProcessGetCurrentThread (pid); 2323 // Make sure we set the current thread so g and p packets return 2324 // the data the gdb will expect. 2325 SetCurrentThread (tid); 2326 2327 SendStopReplyPacketForThread (tid); 2328 } 2329 break; 2330 2331 case eStateInvalid: 2332 case eStateUnloaded: 2333 case eStateExited: 2334 { 2335 char pid_exited_packet[16] = ""; 2336 int pid_status = 0; 2337 // Process exited with exit status 2338 if (!DNBProcessGetExitStatus(pid, &pid_status)) 2339 pid_status = 0; 2340 2341 if (pid_status) 2342 { 2343 if (WIFEXITED (pid_status)) 2344 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status)); 2345 else if (WIFSIGNALED (pid_status)) 2346 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status)); 2347 else if (WIFSTOPPED (pid_status)) 2348 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status)); 2349 } 2350 2351 // If we have an empty exit packet, lets fill one in to be safe. 2352 if (!pid_exited_packet[0]) 2353 { 2354 strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1); 2355 pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0'; 2356 } 2357 2358 return SendPacket (pid_exited_packet); 2359 } 2360 break; 2361 } 2362 return rnb_success; 2363 } 2364 2365 rnb_err_t 2366 RNBRemote::HandlePacket_M (const char *p) 2367 { 2368 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2369 { 2370 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet"); 2371 } 2372 2373 char *c; 2374 p++; 2375 errno = 0; 2376 nub_addr_t addr = strtoull (p, &c, 16); 2377 if (errno != 0 && addr == 0) 2378 { 2379 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet"); 2380 } 2381 if (*c != ',') 2382 { 2383 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet"); 2384 } 2385 2386 /* Advance 'p' to the length part of the packet. */ 2387 p += (c - p) + 1; 2388 2389 errno = 0; 2390 uint32_t length = strtoul (p, &c, 16); 2391 if (errno != 0 && length == 0) 2392 { 2393 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet"); 2394 } 2395 if (length == 0) 2396 { 2397 return SendPacket ("OK"); 2398 } 2399 2400 if (*c != ':') 2401 { 2402 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet"); 2403 } 2404 /* Advance 'p' to the data part of the packet. */ 2405 p += (c - p) + 1; 2406 2407 int datalen = strlen (p); 2408 if (datalen & 0x1) 2409 { 2410 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet"); 2411 } 2412 if (datalen == 0) 2413 { 2414 return SendPacket ("OK"); 2415 } 2416 2417 uint8_t *buf = (uint8_t *) alloca (datalen / 2); 2418 uint8_t *i = buf; 2419 2420 while (*p != '\0' && *(p + 1) != '\0') 2421 { 2422 char hexbuf[3]; 2423 hexbuf[0] = *p; 2424 hexbuf[1] = *(p + 1); 2425 hexbuf[2] = '\0'; 2426 errno = 0; 2427 uint8_t byte = strtoul (hexbuf, NULL, 16); 2428 if (errno != 0 && byte == 0) 2429 { 2430 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet"); 2431 } 2432 *i++ = byte; 2433 p += 2; 2434 } 2435 2436 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf); 2437 if (wrote != length) 2438 return SendPacket ("E09"); 2439 else 2440 return SendPacket ("OK"); 2441 } 2442 2443 2444 rnb_err_t 2445 RNBRemote::HandlePacket_m (const char *p) 2446 { 2447 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2448 { 2449 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet"); 2450 } 2451 2452 char *c; 2453 p++; 2454 errno = 0; 2455 nub_addr_t addr = strtoull (p, &c, 16); 2456 if (errno != 0 && addr == 0) 2457 { 2458 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet"); 2459 } 2460 if (*c != ',') 2461 { 2462 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet"); 2463 } 2464 2465 /* Advance 'p' to the length part of the packet. */ 2466 p += (c - p) + 1; 2467 2468 errno = 0; 2469 uint32_t length = strtoul (p, NULL, 16); 2470 if (errno != 0 && length == 0) 2471 { 2472 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 2473 } 2474 if (length == 0) 2475 { 2476 return SendPacket (""); 2477 } 2478 2479 uint8_t buf[length]; 2480 int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, length, buf); 2481 if (bytes_read == 0) 2482 { 2483 return SendPacket ("E08"); 2484 } 2485 2486 // "The reply may contain fewer bytes than requested if the server was able 2487 // to read only part of the region of memory." 2488 length = bytes_read; 2489 2490 std::ostringstream ostrm; 2491 for (int i = 0; i < length; i++) 2492 ostrm << RAWHEX8(buf[i]); 2493 return SendPacket (ostrm.str ()); 2494 } 2495 2496 rnb_err_t 2497 RNBRemote::HandlePacket_X (const char *p) 2498 { 2499 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2500 { 2501 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 2502 } 2503 2504 char *c; 2505 p++; 2506 errno = 0; 2507 nub_addr_t addr = strtoull (p, &c, 16); 2508 if (errno != 0 && addr == 0) 2509 { 2510 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 2511 } 2512 if (*c != ',') 2513 { 2514 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 2515 } 2516 2517 /* Advance 'p' to the length part of the packet. */ 2518 p += (c - p) + 1; 2519 2520 errno = 0; 2521 int length = strtoul (p, NULL, 16); 2522 if (errno != 0 && length == 0) 2523 { 2524 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 2525 } 2526 2527 // I think gdb sends a zero length write request to test whether this 2528 // packet is accepted. 2529 if (length == 0) 2530 { 2531 return SendPacket ("OK"); 2532 } 2533 2534 std::vector<uint8_t> data = decode_binary_data (c, -1); 2535 std::vector<uint8_t>::const_iterator it; 2536 uint8_t *buf = (uint8_t *) alloca (data.size ()); 2537 uint8_t *i = buf; 2538 for (it = data.begin (); it != data.end (); ++it) 2539 { 2540 *i++ = *it; 2541 } 2542 2543 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf); 2544 if (wrote != data.size ()) 2545 return SendPacket ("E08"); 2546 return SendPacket ("OK"); 2547 } 2548 2549 /* 'g' -- read registers 2550 Get the contents of the registers for the current thread, 2551 send them to gdb. 2552 Should the setting of the Hg packet determine which thread's registers 2553 are returned? */ 2554 2555 rnb_err_t 2556 RNBRemote::HandlePacket_g (const char *p) 2557 { 2558 std::ostringstream ostrm; 2559 if (!m_ctx.HasValidProcessID()) 2560 { 2561 return SendPacket ("E11"); 2562 } 2563 2564 if (g_num_reg_entries == 0) 2565 InitializeRegisters (); 2566 2567 nub_process_t pid = m_ctx.ProcessID (); 2568 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1); 2569 if (tid == INVALID_NUB_THREAD) 2570 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 2571 2572 // Get the register context size first by calling with NULL buffer 2573 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 2574 if (reg_ctx_size) 2575 { 2576 // Now allocate enough space for the entire register context 2577 std::vector<uint8_t> reg_ctx; 2578 reg_ctx.resize(reg_ctx_size); 2579 // Now read the register context 2580 reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, ®_ctx[0], reg_ctx.size()); 2581 if (reg_ctx_size) 2582 { 2583 append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false); 2584 return SendPacket (ostrm.str ()); 2585 } 2586 } 2587 return SendPacket ("E74"); 2588 } 2589 2590 /* 'G XXX...' -- write registers 2591 How is the thread for these specified, beyond "the current thread"? 2592 Does gdb actually use the Hg packet to set this? */ 2593 2594 rnb_err_t 2595 RNBRemote::HandlePacket_G (const char *p) 2596 { 2597 if (!m_ctx.HasValidProcessID()) 2598 { 2599 return SendPacket ("E11"); 2600 } 2601 2602 if (g_num_reg_entries == 0) 2603 InitializeRegisters (); 2604 2605 StringExtractor packet(p); 2606 packet.SetFilePos(1); // Skip the 'G' 2607 2608 nub_process_t pid = m_ctx.ProcessID(); 2609 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 2610 if (tid == INVALID_NUB_THREAD) 2611 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 2612 2613 // Get the register context size first by calling with NULL buffer 2614 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 2615 if (reg_ctx_size) 2616 { 2617 // Now allocate enough space for the entire register context 2618 std::vector<uint8_t> reg_ctx; 2619 reg_ctx.resize(reg_ctx_size); 2620 2621 const nub_size_t bytes_extracted = packet.GetHexBytes (®_ctx[0], reg_ctx.size(), 0xcc); 2622 if (bytes_extracted == reg_ctx.size()) 2623 { 2624 // Now write the register context 2625 reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size()); 2626 if (reg_ctx_size == reg_ctx.size()) 2627 return SendPacket ("OK"); 2628 else 2629 return SendPacket ("E55"); 2630 } 2631 else 2632 { 2633 DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size); 2634 return SendPacket ("E64"); 2635 } 2636 } 2637 return SendPacket ("E65"); 2638 } 2639 2640 static bool 2641 RNBRemoteShouldCancelCallback (void *not_used) 2642 { 2643 RNBRemoteSP remoteSP(g_remoteSP); 2644 if (remoteSP.get() != NULL) 2645 { 2646 RNBRemote* remote = remoteSP.get(); 2647 if (remote->Comm().IsConnected()) 2648 return false; 2649 else 2650 return true; 2651 } 2652 return true; 2653 } 2654 2655 2656 // FORMAT: _MXXXXXX,PPP 2657 // XXXXXX: big endian hex chars 2658 // PPP: permissions can be any combo of r w x chars 2659 // 2660 // RESPONSE: XXXXXX 2661 // XXXXXX: hex address of the newly allocated memory 2662 // EXX: error code 2663 // 2664 // EXAMPLES: 2665 // _M123000,rw 2666 // _M123000,rwx 2667 // _M123000,xw 2668 2669 rnb_err_t 2670 RNBRemote::HandlePacket_AllocateMemory (const char *p) 2671 { 2672 StringExtractor packet (p); 2673 packet.SetFilePos(2); // Skip the "_M" 2674 2675 nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0); 2676 if (size != 0) 2677 { 2678 if (packet.GetChar() == ',') 2679 { 2680 uint32_t permissions = 0; 2681 char ch; 2682 bool success = true; 2683 while (success && (ch = packet.GetChar()) != '\0') 2684 { 2685 switch (ch) 2686 { 2687 case 'r': permissions |= eMemoryPermissionsReadable; break; 2688 case 'w': permissions |= eMemoryPermissionsWritable; break; 2689 case 'x': permissions |= eMemoryPermissionsExecutable; break; 2690 default: success = false; break; 2691 } 2692 } 2693 2694 if (success) 2695 { 2696 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions); 2697 if (addr != INVALID_NUB_ADDRESS) 2698 { 2699 std::ostringstream ostrm; 2700 ostrm << RAW_HEXBASE << addr; 2701 return SendPacket (ostrm.str ()); 2702 } 2703 } 2704 } 2705 } 2706 return SendPacket ("E53"); 2707 } 2708 2709 // FORMAT: _mXXXXXX 2710 // XXXXXX: address that was previosly allocated 2711 // 2712 // RESPONSE: XXXXXX 2713 // OK: address was deallocated 2714 // EXX: error code 2715 // 2716 // EXAMPLES: 2717 // _m123000 2718 2719 rnb_err_t 2720 RNBRemote::HandlePacket_DeallocateMemory (const char *p) 2721 { 2722 StringExtractor packet (p); 2723 packet.SetFilePos(2); // Skip the "_m" 2724 nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS); 2725 2726 if (addr != INVALID_NUB_ADDRESS) 2727 { 2728 if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr)) 2729 return SendPacket ("OK"); 2730 } 2731 return SendPacket ("E54"); 2732 } 2733 2734 2735 // FORMAT: QSaveRegisterState;thread:TTTT; (when thread suffix is supported) 2736 // FORMAT: QSaveRegisterState (when thread suffix is NOT supported) 2737 // TTTT: thread ID in hex 2738 // 2739 // RESPONSE: 2740 // SAVEID: Where SAVEID is a decimal number that represents the save ID 2741 // that can be passed back into a "QRestoreRegisterState" packet 2742 // EXX: error code 2743 // 2744 // EXAMPLES: 2745 // QSaveRegisterState;thread:1E34; (when thread suffix is supported) 2746 // QSaveRegisterState (when thread suffix is NOT supported) 2747 2748 rnb_err_t 2749 RNBRemote::HandlePacket_SaveRegisterState (const char *p) 2750 { 2751 nub_process_t pid = m_ctx.ProcessID (); 2752 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 2753 if (tid == INVALID_NUB_THREAD) 2754 { 2755 if (m_thread_suffix_supported) 2756 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 2757 else 2758 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 2759 } 2760 2761 // Get the register context size first by calling with NULL buffer 2762 const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid); 2763 if (save_id != 0) 2764 { 2765 char response[64]; 2766 snprintf (response, sizeof(response), "%u", save_id); 2767 return SendPacket (response); 2768 } 2769 else 2770 { 2771 return SendPacket ("E75"); 2772 } 2773 } 2774 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT; (when thread suffix is supported) 2775 // FORMAT: QRestoreRegisterState:SAVEID (when thread suffix is NOT supported) 2776 // TTTT: thread ID in hex 2777 // SAVEID: a decimal number that represents the save ID that was 2778 // returned from a call to "QSaveRegisterState" 2779 // 2780 // RESPONSE: 2781 // OK: successfully restored registers for the specified thread 2782 // EXX: error code 2783 // 2784 // EXAMPLES: 2785 // QRestoreRegisterState:1;thread:1E34; (when thread suffix is supported) 2786 // QRestoreRegisterState:1 (when thread suffix is NOT supported) 2787 2788 rnb_err_t 2789 RNBRemote::HandlePacket_RestoreRegisterState (const char *p) 2790 { 2791 nub_process_t pid = m_ctx.ProcessID (); 2792 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 2793 if (tid == INVALID_NUB_THREAD) 2794 { 2795 if (m_thread_suffix_supported) 2796 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 2797 else 2798 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 2799 } 2800 2801 StringExtractor packet (p); 2802 packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:" 2803 const uint32_t save_id = packet.GetU32(0); 2804 2805 if (save_id != 0) 2806 { 2807 // Get the register context size first by calling with NULL buffer 2808 if (DNBThreadRestoreRegisterState(pid, tid, save_id)) 2809 return SendPacket ("OK"); 2810 else 2811 return SendPacket ("E77"); 2812 } 2813 return SendPacket ("E76"); 2814 } 2815 2816 static bool 2817 GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name) 2818 { 2819 bool return_val = true; 2820 while (*p != '\0') 2821 { 2822 char smallbuf[3]; 2823 smallbuf[0] = *p; 2824 smallbuf[1] = *(p + 1); 2825 smallbuf[2] = '\0'; 2826 2827 errno = 0; 2828 int ch = strtoul (smallbuf, NULL, 16); 2829 if (errno != 0 && ch == 0) 2830 { 2831 return_val = false; 2832 break; 2833 } 2834 2835 attach_name.push_back(ch); 2836 p += 2; 2837 } 2838 return return_val; 2839 } 2840 2841 /* 2842 vAttach;pid 2843 2844 Attach to a new process with the specified process ID. pid is a hexadecimal integer 2845 identifying the process. If the stub is currently controlling a process, it is 2846 killed. The attached process is stopped.This packet is only available in extended 2847 mode (see extended mode). 2848 2849 Reply: 2850 "ENN" for an error 2851 "Any Stop Reply Packet" for success 2852 */ 2853 2854 rnb_err_t 2855 RNBRemote::HandlePacket_v (const char *p) 2856 { 2857 if (strcmp (p, "vCont;c") == 0) 2858 { 2859 // Simple continue 2860 return RNBRemote::HandlePacket_c("c"); 2861 } 2862 else if (strcmp (p, "vCont;s") == 0) 2863 { 2864 // Simple step 2865 return RNBRemote::HandlePacket_s("s"); 2866 } 2867 else if (strstr (p, "vCont") == p) 2868 { 2869 typedef struct 2870 { 2871 nub_thread_t tid; 2872 char action; 2873 int signal; 2874 } vcont_action_t; 2875 2876 DNBThreadResumeActions thread_actions; 2877 char *c = (char *)(p += strlen("vCont")); 2878 char *c_end = c + strlen(c); 2879 if (*c == '?') 2880 return SendPacket ("vCont;c;C;s;S"); 2881 2882 while (c < c_end && *c == ';') 2883 { 2884 ++c; // Skip the semi-colon 2885 DNBThreadResumeAction thread_action; 2886 thread_action.tid = INVALID_NUB_THREAD; 2887 thread_action.state = eStateInvalid; 2888 thread_action.signal = 0; 2889 thread_action.addr = INVALID_NUB_ADDRESS; 2890 2891 char action = *c++; 2892 2893 switch (action) 2894 { 2895 case 'C': 2896 errno = 0; 2897 thread_action.signal = strtoul (c, &c, 16); 2898 if (errno != 0) 2899 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 2900 // Fall through to next case... 2901 2902 case 'c': 2903 // Continue 2904 thread_action.state = eStateRunning; 2905 break; 2906 2907 case 'S': 2908 errno = 0; 2909 thread_action.signal = strtoul (c, &c, 16); 2910 if (errno != 0) 2911 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 2912 // Fall through to next case... 2913 2914 case 's': 2915 // Step 2916 thread_action.state = eStateStepping; 2917 break; 2918 2919 default: 2920 HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet"); 2921 break; 2922 } 2923 if (*c == ':') 2924 { 2925 errno = 0; 2926 thread_action.tid = strtoul (++c, &c, 16); 2927 if (errno != 0) 2928 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet"); 2929 } 2930 2931 thread_actions.Append (thread_action); 2932 } 2933 2934 // If a default action for all other threads wasn't mentioned 2935 // then we should stop the threads 2936 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 2937 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize()); 2938 return rnb_success; 2939 } 2940 else if (strstr (p, "vAttach") == p) 2941 { 2942 nub_process_t attach_pid = INVALID_NUB_PROCESS; 2943 char err_str[1024]={'\0'}; 2944 2945 if (strstr (p, "vAttachWait;") == p) 2946 { 2947 p += strlen("vAttachWait;"); 2948 std::string attach_name; 2949 if (!GetProcessNameFrom_vAttach(p, attach_name)) 2950 { 2951 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 2952 } 2953 const bool ignore_existing = true; 2954 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 2955 2956 } 2957 else if (strstr (p, "vAttachOrWait;") == p) 2958 { 2959 p += strlen("vAttachOrWait;"); 2960 std::string attach_name; 2961 if (!GetProcessNameFrom_vAttach(p, attach_name)) 2962 { 2963 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt"); 2964 } 2965 const bool ignore_existing = false; 2966 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 2967 } 2968 else if (strstr (p, "vAttachName;") == p) 2969 { 2970 p += strlen("vAttachName;"); 2971 std::string attach_name; 2972 if (!GetProcessNameFrom_vAttach(p, attach_name)) 2973 { 2974 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt"); 2975 } 2976 2977 attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str)); 2978 2979 } 2980 else if (strstr (p, "vAttach;") == p) 2981 { 2982 p += strlen("vAttach;"); 2983 char *end = NULL; 2984 attach_pid = strtoul (p, &end, 16); // PID will be in hex, so use base 16 to decode 2985 if (p != end && *end == '\0') 2986 { 2987 // Wait at most 30 second for attach 2988 struct timespec attach_timeout_abstime; 2989 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0); 2990 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str)); 2991 } 2992 } 2993 else 2994 { 2995 return HandlePacket_UNIMPLEMENTED(p); 2996 } 2997 2998 2999 if (attach_pid != INVALID_NUB_PROCESS) 3000 { 3001 if (m_ctx.ProcessID() != attach_pid) 3002 m_ctx.SetProcessID(attach_pid); 3003 // Send a stop reply packet to indicate we successfully attached! 3004 NotifyThatProcessStopped (); 3005 return rnb_success; 3006 } 3007 else 3008 { 3009 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic); 3010 if (err_str[0]) 3011 m_ctx.LaunchStatus().SetErrorString(err_str); 3012 else 3013 m_ctx.LaunchStatus().SetErrorString("attach failed"); 3014 return SendPacket ("E01"); // E01 is our magic error value for attach failed. 3015 } 3016 } 3017 3018 // All other failures come through here 3019 return HandlePacket_UNIMPLEMENTED(p); 3020 } 3021 3022 /* 'T XX' -- status of thread 3023 Check if the specified thread is alive. 3024 The thread number is in hex? */ 3025 3026 rnb_err_t 3027 RNBRemote::HandlePacket_T (const char *p) 3028 { 3029 p++; 3030 if (p == NULL || *p == '\0') 3031 { 3032 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet"); 3033 } 3034 if (!m_ctx.HasValidProcessID()) 3035 { 3036 return SendPacket ("E15"); 3037 } 3038 errno = 0; 3039 nub_thread_t tid = strtoul (p, NULL, 16); 3040 if (errno != 0 && tid == 0) 3041 { 3042 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet"); 3043 } 3044 3045 nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid); 3046 if (state == eStateInvalid || state == eStateExited || state == eStateCrashed) 3047 { 3048 return SendPacket ("E16"); 3049 } 3050 3051 return SendPacket ("OK"); 3052 } 3053 3054 3055 rnb_err_t 3056 RNBRemote::HandlePacket_z (const char *p) 3057 { 3058 if (p == NULL || *p == '\0') 3059 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet"); 3060 3061 if (!m_ctx.HasValidProcessID()) 3062 return SendPacket ("E15"); 3063 3064 char packet_cmd = *p++; 3065 char break_type = *p++; 3066 3067 if (*p++ != ',') 3068 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3069 3070 char *c = NULL; 3071 nub_process_t pid = m_ctx.ProcessID(); 3072 errno = 0; 3073 nub_addr_t addr = strtoull (p, &c, 16); 3074 if (errno != 0 && addr == 0) 3075 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet"); 3076 p = c; 3077 if (*p++ != ',') 3078 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3079 3080 errno = 0; 3081 uint32_t byte_size = strtoul (p, &c, 16); 3082 if (errno != 0 && byte_size == 0) 3083 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet"); 3084 3085 if (packet_cmd == 'Z') 3086 { 3087 // set 3088 switch (break_type) 3089 { 3090 case '0': // set software breakpoint 3091 case '1': // set hardware breakpoint 3092 { 3093 // gdb can send multiple Z packets for the same address and 3094 // these calls must be ref counted. 3095 bool hardware = (break_type == '1'); 3096 3097 if (DNBBreakpointSet (pid, addr, byte_size, hardware)) 3098 { 3099 // We successfully created a breakpoint, now lets full out 3100 // a ref count structure with the breakID and add it to our 3101 // map. 3102 return SendPacket ("OK"); 3103 } 3104 else 3105 { 3106 // We failed to set the software breakpoint 3107 return SendPacket ("E09"); 3108 } 3109 } 3110 break; 3111 3112 case '2': // set write watchpoint 3113 case '3': // set read watchpoint 3114 case '4': // set access watchpoint 3115 { 3116 bool hardware = true; 3117 uint32_t watch_flags = 0; 3118 if (break_type == '2') 3119 watch_flags = WATCH_TYPE_WRITE; 3120 else if (break_type == '3') 3121 watch_flags = WATCH_TYPE_READ; 3122 else 3123 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 3124 3125 if (DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware)) 3126 { 3127 return SendPacket ("OK"); 3128 } 3129 else 3130 { 3131 // We failed to set the watchpoint 3132 return SendPacket ("E09"); 3133 } 3134 } 3135 break; 3136 3137 default: 3138 break; 3139 } 3140 } 3141 else if (packet_cmd == 'z') 3142 { 3143 // remove 3144 switch (break_type) 3145 { 3146 case '0': // remove software breakpoint 3147 case '1': // remove hardware breakpoint 3148 if (DNBBreakpointClear (pid, addr)) 3149 { 3150 return SendPacket ("OK"); 3151 } 3152 else 3153 { 3154 return SendPacket ("E08"); 3155 } 3156 break; 3157 3158 case '2': // remove write watchpoint 3159 case '3': // remove read watchpoint 3160 case '4': // remove access watchpoint 3161 if (DNBWatchpointClear (pid, addr)) 3162 { 3163 return SendPacket ("OK"); 3164 } 3165 else 3166 { 3167 return SendPacket ("E08"); 3168 } 3169 break; 3170 3171 default: 3172 break; 3173 } 3174 } 3175 return HandlePacket_UNIMPLEMENTED(p); 3176 } 3177 3178 // Extract the thread number from the thread suffix that might be appended to 3179 // thread specific packets. This will only be enabled if m_thread_suffix_supported 3180 // is true. 3181 nub_thread_t 3182 RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p) 3183 { 3184 if (m_thread_suffix_supported) 3185 { 3186 nub_thread_t tid = INVALID_NUB_THREAD; 3187 if (p) 3188 { 3189 const char *tid_cstr = strstr (p, "thread:"); 3190 if (tid_cstr) 3191 { 3192 tid_cstr += strlen ("thread:"); 3193 tid = strtoul(tid_cstr, NULL, 16); 3194 } 3195 } 3196 return tid; 3197 } 3198 return GetCurrentThread(); 3199 3200 } 3201 3202 /* 'p XX' 3203 print the contents of register X */ 3204 3205 rnb_err_t 3206 RNBRemote::HandlePacket_p (const char *p) 3207 { 3208 if (g_num_reg_entries == 0) 3209 InitializeRegisters (); 3210 3211 if (p == NULL || *p == '\0') 3212 { 3213 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3214 } 3215 if (!m_ctx.HasValidProcessID()) 3216 { 3217 return SendPacket ("E15"); 3218 } 3219 nub_process_t pid = m_ctx.ProcessID(); 3220 errno = 0; 3221 char *tid_cstr = NULL; 3222 uint32_t reg = strtoul (p + 1, &tid_cstr, 16); 3223 if (errno != 0 && reg == 0) 3224 { 3225 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet"); 3226 } 3227 3228 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr); 3229 if (tid == INVALID_NUB_THREAD) 3230 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3231 3232 const register_map_entry_t *reg_entry; 3233 3234 if (reg < g_num_reg_entries) 3235 reg_entry = &g_reg_entries[reg]; 3236 else 3237 reg_entry = NULL; 3238 3239 std::ostringstream ostrm; 3240 if (reg_entry == NULL) 3241 { 3242 DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg); 3243 ostrm << "00000000"; 3244 } 3245 else if (reg_entry->nub_info.reg == -1) 3246 { 3247 if (reg_entry->nub_info.size > 0) 3248 { 3249 std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0'); 3250 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 3251 } 3252 } 3253 else 3254 { 3255 register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL); 3256 } 3257 return SendPacket (ostrm.str()); 3258 } 3259 3260 /* 'Pnn=rrrrr' 3261 Set register number n to value r. 3262 n and r are hex strings. */ 3263 3264 rnb_err_t 3265 RNBRemote::HandlePacket_P (const char *p) 3266 { 3267 if (g_num_reg_entries == 0) 3268 InitializeRegisters (); 3269 3270 if (p == NULL || *p == '\0') 3271 { 3272 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet"); 3273 } 3274 if (!m_ctx.HasValidProcessID()) 3275 { 3276 return SendPacket ("E28"); 3277 } 3278 3279 nub_process_t pid = m_ctx.ProcessID(); 3280 3281 StringExtractor packet (p); 3282 3283 const char cmd_char = packet.GetChar(); 3284 // Register ID is always in big endian 3285 const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX); 3286 const char equal_char = packet.GetChar(); 3287 3288 if (cmd_char != 'P') 3289 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet"); 3290 3291 if (reg == UINT32_MAX) 3292 return SendPacket ("E29"); 3293 3294 if (equal_char != '=') 3295 return SendPacket ("E30"); 3296 3297 const register_map_entry_t *reg_entry; 3298 3299 if (reg >= g_num_reg_entries) 3300 return SendPacket("E47"); 3301 3302 reg_entry = &g_reg_entries[reg]; 3303 3304 if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1) 3305 { 3306 DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg); 3307 return SendPacket("E48"); 3308 } 3309 3310 DNBRegisterValue reg_value; 3311 reg_value.info = reg_entry->nub_info; 3312 packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc); 3313 3314 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3315 if (tid == INVALID_NUB_THREAD) 3316 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3317 3318 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) 3319 { 3320 return SendPacket ("E32"); 3321 } 3322 return SendPacket ("OK"); 3323 } 3324 3325 /* 'c [addr]' 3326 Continue, optionally from a specified address. */ 3327 3328 rnb_err_t 3329 RNBRemote::HandlePacket_c (const char *p) 3330 { 3331 const nub_process_t pid = m_ctx.ProcessID(); 3332 3333 if (pid == INVALID_NUB_PROCESS) 3334 return SendPacket ("E23"); 3335 3336 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 3337 3338 if (*(p + 1) != '\0') 3339 { 3340 action.tid = GetContinueThread(); 3341 errno = 0; 3342 action.addr = strtoull (p + 1, NULL, 16); 3343 if (errno != 0 && action.addr == 0) 3344 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet"); 3345 } 3346 3347 DNBThreadResumeActions thread_actions; 3348 thread_actions.Append(action); 3349 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 3350 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3351 return SendPacket ("E25"); 3352 // Don't send an "OK" packet; response is the stopped/exited message. 3353 return rnb_success; 3354 } 3355 3356 rnb_err_t 3357 RNBRemote::HandlePacket_MemoryRegionInfo (const char *p) 3358 { 3359 /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code) 3360 for the memory region containing a given address and return that information. 3361 3362 Users of this packet must be prepared for three results: 3363 3364 Region information is returned 3365 Region information is unavailable for this address because the address is in unmapped memory 3366 Region lookup cannot be performed on this platform or process is not yet launched 3367 This packet isn't implemented 3368 3369 Examples of use: 3370 qMemoryRegionInfo:3a55140 3371 start:3a50000,size:100000,permissions:rwx 3372 3373 qMemoryRegionInfo:0 3374 error:address in unmapped region 3375 3376 qMemoryRegionInfo:3a551140 (on a different platform) 3377 error:region lookup cannot be performed 3378 3379 qMemoryRegionInfo 3380 OK // this packet is implemented by the remote nub 3381 */ 3382 3383 p += sizeof ("qMemoryRegionInfo") - 1; 3384 if (*p == '\0') 3385 return SendPacket ("OK"); 3386 if (*p++ != ':') 3387 return SendPacket ("E67"); 3388 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) 3389 p += 2; 3390 3391 errno = 0; 3392 uint64_t address = strtoul (p, NULL, 16); 3393 if (errno != 0 && address == 0) 3394 { 3395 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); 3396 } 3397 3398 DNBRegionInfo region_info = { 0, 0, 0 }; 3399 DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info); 3400 std::ostringstream ostrm; 3401 3402 // start:3a50000,size:100000,permissions:rwx 3403 ostrm << "start:" << std::hex << region_info.addr << ';'; 3404 3405 if (region_info.size > 0) 3406 ostrm << "size:" << std::hex << region_info.size << ';'; 3407 3408 if (region_info.permissions) 3409 { 3410 ostrm << "permissions:"; 3411 3412 if (region_info.permissions & eMemoryPermissionsReadable) 3413 ostrm << 'r'; 3414 if (region_info.permissions & eMemoryPermissionsWritable) 3415 ostrm << 'w'; 3416 if (region_info.permissions & eMemoryPermissionsExecutable) 3417 ostrm << 'x'; 3418 ostrm << ';'; 3419 } 3420 return SendPacket (ostrm.str()); 3421 } 3422 3423 // qGetProfileData;scan_type:0xYYYYYYY 3424 rnb_err_t 3425 RNBRemote::HandlePacket_GetProfileData (const char *p) 3426 { 3427 nub_process_t pid = m_ctx.ProcessID(); 3428 if (pid == INVALID_NUB_PROCESS) 3429 return SendPacket ("OK"); 3430 3431 StringExtractor packet(p += sizeof ("qGetProfileData")); 3432 DNBProfileDataScanType scan_type = eProfileAll; 3433 std::string name; 3434 std::string value; 3435 while (packet.GetNameColonValue(name, value)) 3436 { 3437 if (name.compare ("scan_type") == 0) 3438 { 3439 std::istringstream iss(value); 3440 uint32_t int_value = 0; 3441 if (iss >> std::hex >> int_value) 3442 { 3443 scan_type = (DNBProfileDataScanType)int_value; 3444 } 3445 } 3446 } 3447 3448 std::string data = DNBProcessGetProfileData(pid, scan_type); 3449 if (!data.empty()) 3450 { 3451 return SendPacket (data.c_str()); 3452 } 3453 else 3454 { 3455 return SendPacket ("OK"); 3456 } 3457 } 3458 3459 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY 3460 rnb_err_t 3461 RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p) 3462 { 3463 nub_process_t pid = m_ctx.ProcessID(); 3464 if (pid == INVALID_NUB_PROCESS) 3465 return SendPacket ("OK"); 3466 3467 StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling")); 3468 bool enable = false; 3469 uint64_t interval_usec = 0; 3470 DNBProfileDataScanType scan_type = eProfileAll; 3471 std::string name; 3472 std::string value; 3473 while (packet.GetNameColonValue(name, value)) 3474 { 3475 if (name.compare ("enable") == 0) 3476 { 3477 enable = strtoul(value.c_str(), NULL, 10) > 0; 3478 } 3479 else if (name.compare ("interval_usec") == 0) 3480 { 3481 interval_usec = strtoul(value.c_str(), NULL, 10); 3482 } 3483 else if (name.compare ("scan_type") == 0) 3484 { 3485 std::istringstream iss(value); 3486 uint32_t int_value = 0; 3487 if (iss >> std::hex >> int_value) 3488 { 3489 scan_type = (DNBProfileDataScanType)int_value; 3490 } 3491 } 3492 } 3493 3494 if (interval_usec == 0) 3495 { 3496 enable = 0; 3497 } 3498 3499 DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type); 3500 return SendPacket ("OK"); 3501 } 3502 3503 rnb_err_t 3504 RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p) 3505 { 3506 /* This packet simply returns the number of supported hardware watchpoints. 3507 3508 Examples of use: 3509 qWatchpointSupportInfo: 3510 num:4 3511 3512 qWatchpointSupportInfo 3513 OK // this packet is implemented by the remote nub 3514 */ 3515 3516 p += sizeof ("qWatchpointSupportInfo") - 1; 3517 if (*p == '\0') 3518 return SendPacket ("OK"); 3519 if (*p++ != ':') 3520 return SendPacket ("E67"); 3521 3522 errno = 0; 3523 uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID()); 3524 std::ostringstream ostrm; 3525 3526 // size:4 3527 ostrm << "num:" << std::dec << num << ';'; 3528 return SendPacket (ostrm.str()); 3529 } 3530 3531 /* 'C sig [;addr]' 3532 Resume with signal sig, optionally at address addr. */ 3533 3534 rnb_err_t 3535 RNBRemote::HandlePacket_C (const char *p) 3536 { 3537 const nub_process_t pid = m_ctx.ProcessID(); 3538 3539 if (pid == INVALID_NUB_PROCESS) 3540 return SendPacket ("E36"); 3541 3542 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 3543 int process_signo = -1; 3544 if (*(p + 1) != '\0') 3545 { 3546 action.tid = GetContinueThread(); 3547 char *end = NULL; 3548 errno = 0; 3549 process_signo = strtoul (p + 1, &end, 16); 3550 if (errno != 0) 3551 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet"); 3552 else if (*end == ';') 3553 { 3554 errno = 0; 3555 action.addr = strtoull (end + 1, NULL, 16); 3556 if (errno != 0 && action.addr == 0) 3557 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet"); 3558 } 3559 } 3560 3561 DNBThreadResumeActions thread_actions; 3562 thread_actions.Append (action); 3563 thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal); 3564 if (!DNBProcessSignal(pid, process_signo)) 3565 return SendPacket ("E52"); 3566 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3567 return SendPacket ("E38"); 3568 /* Don't send an "OK" packet; response is the stopped/exited message. */ 3569 return rnb_success; 3570 } 3571 3572 //---------------------------------------------------------------------- 3573 // 'D' packet 3574 // Detach from gdb. 3575 //---------------------------------------------------------------------- 3576 rnb_err_t 3577 RNBRemote::HandlePacket_D (const char *p) 3578 { 3579 SendPacket ("OK"); 3580 if (m_ctx.HasValidProcessID()) 3581 DNBProcessDetach(m_ctx.ProcessID()); 3582 return rnb_success; 3583 } 3584 3585 /* 'k' 3586 Kill the inferior process. */ 3587 3588 rnb_err_t 3589 RNBRemote::HandlePacket_k (const char *p) 3590 { 3591 DNBLog ("Got a 'k' packet, killing the inferior process."); 3592 // No response to should be sent to the kill packet 3593 if (m_ctx.HasValidProcessID()) 3594 DNBProcessKill (m_ctx.ProcessID()); 3595 SendPacket ("W09"); 3596 return rnb_success; 3597 } 3598 3599 rnb_err_t 3600 RNBRemote::HandlePacket_stop_process (const char *p) 3601 { 3602 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt 3603 #if defined(TEST_EXIT_ON_INTERRUPT) 3604 rnb_err_t err = HandlePacket_k (p); 3605 m_comm.Disconnect(true); 3606 return err; 3607 #else 3608 DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP); 3609 //DNBProcessSignal (m_ctx.ProcessID(), SIGINT); 3610 // Do not send any response packet! Wait for the stop reply packet to naturally happen 3611 return rnb_success; 3612 #endif 3613 } 3614 3615 /* 's' 3616 Step the inferior process. */ 3617 3618 rnb_err_t 3619 RNBRemote::HandlePacket_s (const char *p) 3620 { 3621 const nub_process_t pid = m_ctx.ProcessID(); 3622 if (pid == INVALID_NUB_PROCESS) 3623 return SendPacket ("E32"); 3624 3625 // Hardware supported stepping not supported on arm 3626 nub_thread_t tid = GetContinueThread (); 3627 if (tid == 0 || tid == -1) 3628 tid = GetCurrentThread(); 3629 3630 if (tid == INVALID_NUB_THREAD) 3631 return SendPacket ("E33"); 3632 3633 DNBThreadResumeActions thread_actions; 3634 thread_actions.AppendAction(tid, eStateStepping); 3635 3636 // Make all other threads stop when we are stepping 3637 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 3638 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3639 return SendPacket ("E49"); 3640 // Don't send an "OK" packet; response is the stopped/exited message. 3641 return rnb_success; 3642 } 3643 3644 /* 'S sig [;addr]' 3645 Step with signal sig, optionally at address addr. */ 3646 3647 rnb_err_t 3648 RNBRemote::HandlePacket_S (const char *p) 3649 { 3650 const nub_process_t pid = m_ctx.ProcessID(); 3651 if (pid == INVALID_NUB_PROCESS) 3652 return SendPacket ("E36"); 3653 3654 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 3655 3656 if (*(p + 1) != '\0') 3657 { 3658 char *end = NULL; 3659 errno = 0; 3660 action.signal = strtoul (p + 1, &end, 16); 3661 if (errno != 0) 3662 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet"); 3663 else if (*end == ';') 3664 { 3665 errno = 0; 3666 action.addr = strtoull (end + 1, NULL, 16); 3667 if (errno != 0 && action.addr == 0) 3668 { 3669 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet"); 3670 } 3671 } 3672 } 3673 3674 action.tid = GetContinueThread (); 3675 if (action.tid == 0 || action.tid == -1) 3676 return SendPacket ("E40"); 3677 3678 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 3679 if (tstate == eStateInvalid || tstate == eStateExited) 3680 return SendPacket ("E37"); 3681 3682 3683 DNBThreadResumeActions thread_actions; 3684 thread_actions.Append (action); 3685 3686 // Make all other threads stop when we are stepping 3687 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 3688 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3689 return SendPacket ("E39"); 3690 3691 // Don't send an "OK" packet; response is the stopped/exited message. 3692 return rnb_success; 3693 } 3694 3695 rnb_err_t 3696 RNBRemote::HandlePacket_qHostInfo (const char *p) 3697 { 3698 std::ostringstream strm; 3699 3700 uint32_t cputype, is_64_bit_capable; 3701 size_t len = sizeof(cputype); 3702 bool promoted_to_64 = false; 3703 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 3704 { 3705 len = sizeof (is_64_bit_capable); 3706 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 3707 { 3708 if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0)) 3709 { 3710 promoted_to_64 = true; 3711 cputype |= CPU_ARCH_ABI64; 3712 } 3713 } 3714 3715 strm << "cputype:" << std::dec << cputype << ';'; 3716 } 3717 3718 uint32_t cpusubtype; 3719 len = sizeof(cpusubtype); 3720 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) 3721 { 3722 if (promoted_to_64 && 3723 cputype == CPU_TYPE_X86_64 && 3724 cpusubtype == CPU_SUBTYPE_486) 3725 cpusubtype = CPU_SUBTYPE_X86_64_ALL; 3726 3727 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 3728 } 3729 3730 // The OS in the triple should be "ios" or "macosx" which doesn't match our 3731 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 3732 // this for now. 3733 if (cputype == CPU_TYPE_ARM) 3734 { 3735 strm << "ostype:ios;"; 3736 // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 3737 strm << "watchpoint_exceptions_received:before;"; 3738 } 3739 else 3740 { 3741 strm << "ostype:macosx;"; 3742 strm << "watchpoint_exceptions_received:after;"; 3743 } 3744 // char ostype[64]; 3745 // len = sizeof(ostype); 3746 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 3747 // { 3748 // len = strlen(ostype); 3749 // std::transform (ostype, ostype + len, ostype, tolower); 3750 // strm << "ostype:" << std::dec << ostype << ';'; 3751 // } 3752 3753 strm << "vendor:apple;"; 3754 3755 #if defined (__LITTLE_ENDIAN__) 3756 strm << "endian:little;"; 3757 #elif defined (__BIG_ENDIAN__) 3758 strm << "endian:big;"; 3759 #elif defined (__PDP_ENDIAN__) 3760 strm << "endian:pdp;"; 3761 #endif 3762 3763 if (promoted_to_64) 3764 strm << "ptrsize:8;"; 3765 else 3766 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 3767 return SendPacket (strm.str()); 3768 } 3769 3770 rnb_err_t 3771 RNBRemote::HandlePacket_qGDBServerVersion (const char *p) 3772 { 3773 std::ostringstream strm; 3774 3775 if (DEBUGSERVER_PROGRAM_NAME) 3776 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 3777 else 3778 strm << "name:debugserver;"; 3779 strm << "version:" << DEBUGSERVER_VERSION_NUM << ";"; 3780 3781 return SendPacket (strm.str()); 3782 } 3783 3784 // Note that all numeric values returned by qProcessInfo are hex encoded, 3785 // including the pid and the cpu type. 3786 3787 rnb_err_t 3788 RNBRemote::HandlePacket_qProcessInfo (const char *p) 3789 { 3790 nub_process_t pid; 3791 std::ostringstream rep; 3792 3793 // If we haven't run the process yet, return an error. 3794 if (!m_ctx.HasValidProcessID()) 3795 return SendPacket ("E68"); 3796 3797 pid = m_ctx.ProcessID(); 3798 3799 rep << "pid:" << std::hex << pid << ";"; 3800 3801 int procpid_mib[4]; 3802 procpid_mib[0] = CTL_KERN; 3803 procpid_mib[1] = KERN_PROC; 3804 procpid_mib[2] = KERN_PROC_PID; 3805 procpid_mib[3] = pid; 3806 struct kinfo_proc proc_kinfo; 3807 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 3808 3809 if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) 3810 { 3811 if (proc_kinfo_size > 0) 3812 { 3813 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";"; 3814 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";"; 3815 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";"; 3816 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";"; 3817 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 3818 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";"; 3819 } 3820 } 3821 3822 cpu_type_t cputype = DNBProcessGetCPUType (pid); 3823 if (cputype == 0) 3824 { 3825 DNBLog ("Unable to get the process cpu_type, making a best guess."); 3826 cputype = best_guess_cpu_type(); 3827 } 3828 3829 if (cputype != 0) 3830 { 3831 rep << "cputype:" << std::hex << cputype << ";"; 3832 } 3833 3834 uint32_t cpusubtype; 3835 size_t cpusubtype_len = sizeof(cpusubtype); 3836 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0) 3837 { 3838 if (cputype == CPU_TYPE_X86_64 && cpusubtype == CPU_SUBTYPE_486) 3839 { 3840 cpusubtype = CPU_SUBTYPE_X86_64_ALL; 3841 } 3842 3843 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 3844 } 3845 3846 // The OS in the triple should be "ios" or "macosx" which doesn't match our 3847 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 3848 // this for now. 3849 if (cputype == CPU_TYPE_ARM) 3850 rep << "ostype:ios;"; 3851 else 3852 rep << "ostype:macosx;"; 3853 3854 rep << "vendor:apple;"; 3855 3856 #if defined (__LITTLE_ENDIAN__) 3857 rep << "endian:little;"; 3858 #elif defined (__BIG_ENDIAN__) 3859 rep << "endian:big;"; 3860 #elif defined (__PDP_ENDIAN__) 3861 rep << "endian:pdp;"; 3862 #endif 3863 3864 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE) 3865 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 3866 kern_return_t kr; 3867 x86_thread_state_t gp_regs; 3868 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 3869 kr = thread_get_state (thread, x86_THREAD_STATE, 3870 (thread_state_t) &gp_regs, &gp_count); 3871 if (kr == KERN_SUCCESS) 3872 { 3873 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 3874 rep << "ptrsize:8;"; 3875 else 3876 rep << "ptrsize:4;"; 3877 } 3878 #elif defined (__arm__) 3879 rep << "ptrsize:4;"; 3880 #endif 3881 3882 return SendPacket (rep.str()); 3883 } 3884 3885