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 DNBLogThreaded("%s -> %u", reg_entry.nub_info.name, reg_data_offset); 919 reg_data_offset += reg_entry.nub_info.size; 920 } 921 922 g_dynamic_register_map.push_back (reg_entry); 923 } 924 } 925 926 // Now we must find any regsiters whose values are in other registers and fix up 927 // the offsets since we removed all gaps... 928 for (auto ®_entry: g_dynamic_register_map) 929 { 930 if (reg_entry.nub_info.value_regs) 931 { 932 uint32_t new_offset = UINT32_MAX; 933 for (size_t i=0; reg_entry.nub_info.value_regs[i] != NULL; ++i) 934 { 935 const char *name = reg_entry.nub_info.value_regs[i]; 936 auto pos = name_to_regnum.find(name); 937 if (pos != name_to_regnum.end()) 938 { 939 regnum = pos->second; 940 reg_entry.value_regnums.push_back(regnum); 941 if (regnum < g_dynamic_register_map.size()) 942 { 943 // The offset for value_regs registers is the offset within the register with the lowest offset 944 const uint32_t reg_offset = g_dynamic_register_map[regnum].offset + reg_entry.nub_info.offset; 945 if (new_offset > reg_offset) 946 new_offset = reg_offset; 947 } 948 } 949 } 950 951 if (new_offset != UINT32_MAX) 952 { 953 reg_entry.offset = new_offset; 954 } 955 else 956 { 957 DNBLogThreaded("no offset was calculated entry for register %s", reg_entry.nub_info.name); 958 reg_entry.offset = UINT32_MAX; 959 } 960 } 961 962 if (reg_entry.nub_info.update_regs) 963 { 964 for (size_t i=0; reg_entry.nub_info.update_regs[i] != NULL; ++i) 965 { 966 const char *name = reg_entry.nub_info.update_regs[i]; 967 auto pos = name_to_regnum.find(name); 968 if (pos != name_to_regnum.end()) 969 { 970 regnum = pos->second; 971 reg_entry.invalidate_regnums.push_back(regnum); 972 } 973 } 974 } 975 } 976 977 978 // for (auto ®_entry: g_dynamic_register_map) 979 // { 980 // DNBLogThreaded("%4i: size = %3u, pseudo = %i, name = %s", 981 // reg_entry.offset, 982 // reg_entry.nub_info.size, 983 // reg_entry.nub_info.value_regs != NULL, 984 // reg_entry.nub_info.name); 985 // } 986 987 g_reg_entries = g_dynamic_register_map.data(); 988 g_num_reg_entries = g_dynamic_register_map.size(); 989 } 990 return true; 991 } 992 993 /* The inferior has stopped executing; send a packet 994 to gdb to let it know. */ 995 996 void 997 RNBRemote::NotifyThatProcessStopped (void) 998 { 999 RNBRemote::HandlePacket_last_signal (NULL); 1000 return; 1001 } 1002 1003 1004 /* 'A arglen,argnum,arg,...' 1005 Update the inferior context CTX with the program name and arg 1006 list. 1007 The documentation for this packet is underwhelming but my best reading 1008 of this is that it is a series of (len, position #, arg)'s, one for 1009 each argument with "arg" hex encoded (two 0-9a-f chars?). 1010 Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either 1011 is sufficient to get around the "," position separator escape issue. 1012 1013 e.g. our best guess for a valid 'A' packet for "gdb -q a.out" is 1014 1015 6,0,676462,4,1,2d71,10,2,612e6f7574 1016 1017 Note that "argnum" and "arglen" are numbers in base 10. Again, that's 1018 not documented either way but I'm assuming it's so. */ 1019 1020 rnb_err_t 1021 RNBRemote::HandlePacket_A (const char *p) 1022 { 1023 if (p == NULL || *p == '\0') 1024 { 1025 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Null packet for 'A' pkt"); 1026 } 1027 p++; 1028 if (*p == '\0' || !isdigit (*p)) 1029 { 1030 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not specified on 'A' pkt"); 1031 } 1032 1033 /* I promise I don't modify it anywhere in this function. strtoul()'s 1034 2nd arg has to be non-const which makes it problematic to step 1035 through the string easily. */ 1036 char *buf = const_cast<char *>(p); 1037 1038 RNBContext& ctx = Context(); 1039 1040 while (*buf != '\0') 1041 { 1042 int arglen, argnum; 1043 std::string arg; 1044 char *c; 1045 1046 errno = 0; 1047 arglen = strtoul (buf, &c, 10); 1048 if (errno != 0 && arglen == 0) 1049 { 1050 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not a number on 'A' pkt"); 1051 } 1052 if (*c != ',') 1053 { 1054 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt"); 1055 } 1056 buf = c + 1; 1057 1058 errno = 0; 1059 argnum = strtoul (buf, &c, 10); 1060 if (errno != 0 && argnum == 0) 1061 { 1062 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "argnum not a number on 'A' pkt"); 1063 } 1064 if (*c != ',') 1065 { 1066 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt"); 1067 } 1068 buf = c + 1; 1069 1070 c = buf; 1071 buf = buf + arglen; 1072 while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0') 1073 { 1074 char smallbuf[3]; 1075 smallbuf[0] = *c; 1076 smallbuf[1] = *(c + 1); 1077 smallbuf[2] = '\0'; 1078 1079 errno = 0; 1080 int ch = strtoul (smallbuf, NULL, 16); 1081 if (errno != 0 && ch == 0) 1082 { 1083 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'A' pkt"); 1084 } 1085 1086 arg.push_back(ch); 1087 c += 2; 1088 } 1089 1090 ctx.PushArgument (arg.c_str()); 1091 if (*buf == ',') 1092 buf++; 1093 } 1094 SendPacket ("OK"); 1095 1096 return rnb_success; 1097 } 1098 1099 /* 'H c t' 1100 Set the thread for subsequent actions; 'c' for step/continue ops, 1101 'g' for other ops. -1 means all threads, 0 means any thread. */ 1102 1103 rnb_err_t 1104 RNBRemote::HandlePacket_H (const char *p) 1105 { 1106 p++; // skip 'H' 1107 if (*p != 'c' && *p != 'g') 1108 { 1109 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing 'c' or 'g' type in H packet"); 1110 } 1111 1112 if (!m_ctx.HasValidProcessID()) 1113 { 1114 // We allow gdb to connect to a server that hasn't started running 1115 // the target yet. gdb still wants to ask questions about it and 1116 // freaks out if it gets an error. So just return OK here. 1117 } 1118 1119 errno = 0; 1120 nub_thread_t tid = strtoul (p + 1, NULL, 16); 1121 if (errno != 0 && tid == 0) 1122 { 1123 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in H packet"); 1124 } 1125 if (*p == 'c') 1126 SetContinueThread (tid); 1127 if (*p == 'g') 1128 SetCurrentThread (tid); 1129 1130 return SendPacket ("OK"); 1131 } 1132 1133 1134 rnb_err_t 1135 RNBRemote::HandlePacket_qLaunchSuccess (const char *p) 1136 { 1137 if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Error() == 0) 1138 return SendPacket("OK"); 1139 std::ostringstream ret_str; 1140 std::string status_str; 1141 ret_str << "E" << m_ctx.LaunchStatusAsString(status_str); 1142 1143 return SendPacket (ret_str.str()); 1144 } 1145 1146 rnb_err_t 1147 RNBRemote::HandlePacket_qShlibInfoAddr (const char *p) 1148 { 1149 if (m_ctx.HasValidProcessID()) 1150 { 1151 nub_addr_t shlib_info_addr = DNBProcessGetSharedLibraryInfoAddress(m_ctx.ProcessID()); 1152 if (shlib_info_addr != INVALID_NUB_ADDRESS) 1153 { 1154 std::ostringstream ostrm; 1155 ostrm << RAW_HEXBASE << shlib_info_addr; 1156 return SendPacket (ostrm.str ()); 1157 } 1158 } 1159 return SendPacket ("E44"); 1160 } 1161 1162 rnb_err_t 1163 RNBRemote::HandlePacket_qStepPacketSupported (const char *p) 1164 { 1165 // Normally the "s" packet is mandatory, yet in gdb when using ARM, they 1166 // get around the need for this packet by implementing software single 1167 // stepping from gdb. Current versions of debugserver do support the "s" 1168 // packet, yet some older versions do not. We need a way to tell if this 1169 // packet is supported so we can disable software single stepping in gdb 1170 // for remote targets (so the "s" packet will get used). 1171 return SendPacket("OK"); 1172 } 1173 1174 rnb_err_t 1175 RNBRemote::HandlePacket_qSyncThreadStateSupported (const char *p) 1176 { 1177 // We support attachOrWait meaning attach if the process exists, otherwise wait to attach. 1178 return SendPacket("OK"); 1179 } 1180 1181 rnb_err_t 1182 RNBRemote::HandlePacket_qVAttachOrWaitSupported (const char *p) 1183 { 1184 // We support attachOrWait meaning attach if the process exists, otherwise wait to attach. 1185 return SendPacket("OK"); 1186 } 1187 1188 rnb_err_t 1189 RNBRemote::HandlePacket_qThreadStopInfo (const char *p) 1190 { 1191 p += strlen ("qThreadStopInfo"); 1192 nub_thread_t tid = strtoul(p, 0, 16); 1193 return SendStopReplyPacketForThread (tid); 1194 } 1195 1196 rnb_err_t 1197 RNBRemote::HandlePacket_qThreadInfo (const char *p) 1198 { 1199 // We allow gdb to connect to a server that hasn't started running 1200 // the target yet. gdb still wants to ask questions about it and 1201 // freaks out if it gets an error. So just return OK here. 1202 nub_process_t pid = m_ctx.ProcessID(); 1203 if (pid == INVALID_NUB_PROCESS) 1204 return SendPacket ("OK"); 1205 1206 // Only "qfThreadInfo" and "qsThreadInfo" get into this function so 1207 // we only need to check the second byte to tell which is which 1208 if (p[1] == 'f') 1209 { 1210 nub_size_t numthreads = DNBProcessGetNumThreads (pid); 1211 std::ostringstream ostrm; 1212 ostrm << "m"; 1213 bool first = true; 1214 for (nub_size_t i = 0; i < numthreads; ++i) 1215 { 1216 if (first) 1217 first = false; 1218 else 1219 ostrm << ","; 1220 nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i); 1221 ostrm << std::hex << th; 1222 } 1223 return SendPacket (ostrm.str ()); 1224 } 1225 else 1226 { 1227 return SendPacket ("l"); 1228 } 1229 } 1230 1231 rnb_err_t 1232 RNBRemote::HandlePacket_qThreadExtraInfo (const char *p) 1233 { 1234 // We allow gdb to connect to a server that hasn't started running 1235 // the target yet. gdb still wants to ask questions about it and 1236 // freaks out if it gets an error. So just return OK here. 1237 nub_process_t pid = m_ctx.ProcessID(); 1238 if (pid == INVALID_NUB_PROCESS) 1239 return SendPacket ("OK"); 1240 1241 /* This is supposed to return a string like 'Runnable' or 1242 'Blocked on Mutex'. 1243 The returned string is formatted like the "A" packet - a 1244 sequence of letters encoded in as 2-hex-chars-per-letter. */ 1245 p += strlen ("qThreadExtraInfo"); 1246 if (*p++ != ',') 1247 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Illformed qThreadExtraInfo packet"); 1248 errno = 0; 1249 nub_thread_t tid = strtoul (p, NULL, 16); 1250 if (errno != 0 && tid == 0) 1251 { 1252 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in qThreadExtraInfo packet"); 1253 } 1254 1255 const char * threadInfo = DNBThreadGetInfo(pid, tid); 1256 if (threadInfo != NULL && threadInfo[0]) 1257 { 1258 return SendHexEncodedBytePacket(NULL, threadInfo, strlen(threadInfo), NULL); 1259 } 1260 else 1261 { 1262 // "OK" == 4f6b 1263 // Return "OK" as a ASCII hex byte stream if things go wrong 1264 return SendPacket ("4f6b"); 1265 } 1266 1267 return SendPacket (""); 1268 } 1269 1270 1271 const char *k_space_delimiters = " \t"; 1272 static void 1273 skip_spaces (std::string &line) 1274 { 1275 if (!line.empty()) 1276 { 1277 size_t space_pos = line.find_first_not_of (k_space_delimiters); 1278 if (space_pos > 0) 1279 line.erase(0, space_pos); 1280 } 1281 } 1282 1283 static std::string 1284 get_identifier (std::string &line) 1285 { 1286 std::string word; 1287 skip_spaces (line); 1288 const size_t line_size = line.size(); 1289 size_t end_pos; 1290 for (end_pos = 0; end_pos < line_size; ++end_pos) 1291 { 1292 if (end_pos == 0) 1293 { 1294 if (isalpha(line[end_pos]) || line[end_pos] == '_') 1295 continue; 1296 } 1297 else if (isalnum(line[end_pos]) || line[end_pos] == '_') 1298 continue; 1299 break; 1300 } 1301 word.assign (line, 0, end_pos); 1302 line.erase(0, end_pos); 1303 return word; 1304 } 1305 1306 static std::string 1307 get_operator (std::string &line) 1308 { 1309 std::string op; 1310 skip_spaces (line); 1311 if (!line.empty()) 1312 { 1313 if (line[0] == '=') 1314 { 1315 op = '='; 1316 line.erase(0,1); 1317 } 1318 } 1319 return op; 1320 } 1321 1322 static std::string 1323 get_value (std::string &line) 1324 { 1325 std::string value; 1326 skip_spaces (line); 1327 if (!line.empty()) 1328 { 1329 value.swap(line); 1330 } 1331 return value; 1332 } 1333 1334 extern void FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args); 1335 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args); 1336 1337 rnb_err_t 1338 RNBRemote::HandlePacket_qRcmd (const char *p) 1339 { 1340 const char *c = p + strlen("qRcmd,"); 1341 std::string line; 1342 while (c[0] && c[1]) 1343 { 1344 char smallbuf[3] = { c[0], c[1], '\0' }; 1345 errno = 0; 1346 int ch = strtoul (smallbuf, NULL, 16); 1347 if (errno != 0 && ch == 0) 1348 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in payload of qRcmd packet"); 1349 line.push_back(ch); 1350 c += 2; 1351 } 1352 if (*c == '\0') 1353 { 1354 std::string command = get_identifier(line); 1355 if (command.compare("set") == 0) 1356 { 1357 std::string variable = get_identifier (line); 1358 std::string op = get_operator (line); 1359 std::string value = get_value (line); 1360 if (variable.compare("logfile") == 0) 1361 { 1362 FILE *log_file = fopen(value.c_str(), "w"); 1363 if (log_file) 1364 { 1365 DNBLogSetLogCallback(FileLogCallback, log_file); 1366 return SendPacket ("OK"); 1367 } 1368 return SendPacket ("E71"); 1369 } 1370 else if (variable.compare("logmask") == 0) 1371 { 1372 char *end; 1373 errno = 0; 1374 uint32_t logmask = strtoul (value.c_str(), &end, 0); 1375 if (errno == 0 && end && *end == '\0') 1376 { 1377 DNBLogSetLogMask (logmask); 1378 if (!DNBLogGetLogCallback()) 1379 DNBLogSetLogCallback(ASLLogCallback, NULL); 1380 return SendPacket ("OK"); 1381 } 1382 errno = 0; 1383 logmask = strtoul (value.c_str(), &end, 16); 1384 if (errno == 0 && end && *end == '\0') 1385 { 1386 DNBLogSetLogMask (logmask); 1387 return SendPacket ("OK"); 1388 } 1389 return SendPacket ("E72"); 1390 } 1391 return SendPacket ("E70"); 1392 } 1393 return SendPacket ("E69"); 1394 } 1395 return SendPacket ("E73"); 1396 } 1397 1398 rnb_err_t 1399 RNBRemote::HandlePacket_qC (const char *p) 1400 { 1401 nub_process_t pid; 1402 std::ostringstream rep; 1403 // If we haven't run the process yet, we tell the debugger the 1404 // pid is 0. That way it can know to tell use to run later on. 1405 if (m_ctx.HasValidProcessID()) 1406 pid = m_ctx.ProcessID(); 1407 else 1408 pid = 0; 1409 rep << "QC" << std::hex << pid; 1410 return SendPacket (rep.str()); 1411 } 1412 1413 rnb_err_t 1414 RNBRemote::HandlePacket_qGetPid (const char *p) 1415 { 1416 nub_process_t pid; 1417 std::ostringstream rep; 1418 // If we haven't run the process yet, we tell the debugger the 1419 // pid is 0. That way it can know to tell use to run later on. 1420 if (m_ctx.HasValidProcessID()) 1421 pid = m_ctx.ProcessID(); 1422 else 1423 pid = 0; 1424 rep << std::hex << pid; 1425 return SendPacket (rep.str()); 1426 } 1427 1428 rnb_err_t 1429 RNBRemote::HandlePacket_qRegisterInfo (const char *p) 1430 { 1431 if (g_num_reg_entries == 0) 1432 InitializeRegisters (); 1433 1434 p += strlen ("qRegisterInfo"); 1435 1436 nub_size_t num_reg_sets = 0; 1437 const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo (&num_reg_sets); 1438 uint32_t reg_num = strtoul(p, 0, 16); 1439 1440 if (reg_num < g_num_reg_entries) 1441 { 1442 const register_map_entry_t *reg_entry = &g_reg_entries[reg_num]; 1443 std::ostringstream ostrm; 1444 if (reg_entry->nub_info.name) 1445 ostrm << "name:" << reg_entry->nub_info.name << ';'; 1446 if (reg_entry->nub_info.alt) 1447 ostrm << "alt-name:" << reg_entry->nub_info.alt << ';'; 1448 1449 ostrm << "bitsize:" << std::dec << reg_entry->nub_info.size * 8 << ';'; 1450 ostrm << "offset:" << std::dec << reg_entry->offset << ';'; 1451 1452 switch (reg_entry->nub_info.type) 1453 { 1454 case Uint: ostrm << "encoding:uint;"; break; 1455 case Sint: ostrm << "encoding:sint;"; break; 1456 case IEEE754: ostrm << "encoding:ieee754;"; break; 1457 case Vector: ostrm << "encoding:vector;"; break; 1458 } 1459 1460 switch (reg_entry->nub_info.format) 1461 { 1462 case Binary: ostrm << "format:binary;"; break; 1463 case Decimal: ostrm << "format:decimal;"; break; 1464 case Hex: ostrm << "format:hex;"; break; 1465 case Float: ostrm << "format:float;"; break; 1466 case VectorOfSInt8: ostrm << "format:vector-sint8;"; break; 1467 case VectorOfUInt8: ostrm << "format:vector-uint8;"; break; 1468 case VectorOfSInt16: ostrm << "format:vector-sint16;"; break; 1469 case VectorOfUInt16: ostrm << "format:vector-uint16;"; break; 1470 case VectorOfSInt32: ostrm << "format:vector-sint32;"; break; 1471 case VectorOfUInt32: ostrm << "format:vector-uint32;"; break; 1472 case VectorOfFloat32: ostrm << "format:vector-float32;"; break; 1473 case VectorOfUInt128: ostrm << "format:vector-uint128;"; break; 1474 }; 1475 1476 if (reg_set_info && reg_entry->nub_info.set < num_reg_sets) 1477 ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';'; 1478 1479 if (reg_entry->nub_info.reg_gcc != INVALID_NUB_REGNUM) 1480 ostrm << "gcc:" << std::dec << reg_entry->nub_info.reg_gcc << ';'; 1481 1482 if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM) 1483 ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';'; 1484 1485 switch (reg_entry->nub_info.reg_generic) 1486 { 1487 case GENERIC_REGNUM_FP: ostrm << "generic:fp;"; break; 1488 case GENERIC_REGNUM_PC: ostrm << "generic:pc;"; break; 1489 case GENERIC_REGNUM_SP: ostrm << "generic:sp;"; break; 1490 case GENERIC_REGNUM_RA: ostrm << "generic:ra;"; break; 1491 case GENERIC_REGNUM_FLAGS: ostrm << "generic:flags;"; break; 1492 case GENERIC_REGNUM_ARG1: ostrm << "generic:arg1;"; break; 1493 case GENERIC_REGNUM_ARG2: ostrm << "generic:arg2;"; break; 1494 case GENERIC_REGNUM_ARG3: ostrm << "generic:arg3;"; break; 1495 case GENERIC_REGNUM_ARG4: ostrm << "generic:arg4;"; break; 1496 case GENERIC_REGNUM_ARG5: ostrm << "generic:arg5;"; break; 1497 case GENERIC_REGNUM_ARG6: ostrm << "generic:arg6;"; break; 1498 case GENERIC_REGNUM_ARG7: ostrm << "generic:arg7;"; break; 1499 case GENERIC_REGNUM_ARG8: ostrm << "generic:arg8;"; break; 1500 default: break; 1501 } 1502 1503 if (!reg_entry->value_regnums.empty()) 1504 { 1505 ostrm << "container-regs:"; 1506 for (size_t i=0, n=reg_entry->value_regnums.size(); i < n; ++i) 1507 { 1508 if (i > 0) 1509 ostrm << ','; 1510 ostrm << RAW_HEXBASE << reg_entry->value_regnums[i]; 1511 } 1512 ostrm << ';'; 1513 } 1514 1515 if (!reg_entry->invalidate_regnums.empty()) 1516 { 1517 ostrm << "invalidate-regs:"; 1518 for (size_t i=0, n=reg_entry->invalidate_regnums.size(); i < n; ++i) 1519 { 1520 if (i > 0) 1521 ostrm << ','; 1522 ostrm << RAW_HEXBASE << reg_entry->invalidate_regnums[i]; 1523 } 1524 ostrm << ';'; 1525 } 1526 1527 return SendPacket (ostrm.str ()); 1528 } 1529 return SendPacket ("E45"); 1530 } 1531 1532 1533 /* This expects a packet formatted like 1534 1535 QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE; 1536 1537 with the "QSetLogging:" already removed from the start. Maybe in the 1538 future this packet will include other keyvalue pairs like 1539 1540 QSetLogging:bitmask=LOG_ALL;mode=asl; 1541 */ 1542 1543 rnb_err_t 1544 set_logging (const char *p) 1545 { 1546 int bitmask = 0; 1547 while (p && *p != '\0') 1548 { 1549 if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0) 1550 { 1551 p += sizeof ("bitmask=") - 1; 1552 while (p && *p != '\0' && *p != ';') 1553 { 1554 if (*p == '|') 1555 p++; 1556 1557 // to regenerate the LOG_ entries (not including the LOG_RNB entries) 1558 // $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 'LOG_HI|LOG_LO' | awk '{print $2}'` 1559 // do 1560 // echo " else if (strncmp (p, \"$logname\", sizeof (\"$logname\") - 1) == 0)" 1561 // echo " {" 1562 // echo " p += sizeof (\"$logname\") - 1;" 1563 // echo " bitmask |= $logname;" 1564 // echo " }" 1565 // done 1566 if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0) 1567 { 1568 p += sizeof ("LOG_VERBOSE") - 1; 1569 bitmask |= LOG_VERBOSE; 1570 } 1571 else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0) 1572 { 1573 p += sizeof ("LOG_PROCESS") - 1; 1574 bitmask |= LOG_PROCESS; 1575 } 1576 else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0) 1577 { 1578 p += sizeof ("LOG_THREAD") - 1; 1579 bitmask |= LOG_THREAD; 1580 } 1581 else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0) 1582 { 1583 p += sizeof ("LOG_EXCEPTIONS") - 1; 1584 bitmask |= LOG_EXCEPTIONS; 1585 } 1586 else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0) 1587 { 1588 p += sizeof ("LOG_SHLIB") - 1; 1589 bitmask |= LOG_SHLIB; 1590 } 1591 else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0) 1592 { 1593 p += sizeof ("LOG_MEMORY") - 1; 1594 bitmask |= LOG_MEMORY; 1595 } 1596 else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0) 1597 { 1598 p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1; 1599 bitmask |= LOG_MEMORY_DATA_SHORT; 1600 } 1601 else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0) 1602 { 1603 p += sizeof ("LOG_MEMORY_DATA_LONG") - 1; 1604 bitmask |= LOG_MEMORY_DATA_LONG; 1605 } 1606 else if (strncmp (p, "LOG_MEMORY_PROTECTIONS", sizeof ("LOG_MEMORY_PROTECTIONS") - 1) == 0) 1607 { 1608 p += sizeof ("LOG_MEMORY_PROTECTIONS") - 1; 1609 bitmask |= LOG_MEMORY_PROTECTIONS; 1610 } 1611 else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0) 1612 { 1613 p += sizeof ("LOG_BREAKPOINTS") - 1; 1614 bitmask |= LOG_BREAKPOINTS; 1615 } 1616 else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0) 1617 { 1618 p += sizeof ("LOG_EVENTS") - 1; 1619 bitmask |= LOG_EVENTS; 1620 } 1621 else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0) 1622 { 1623 p += sizeof ("LOG_WATCHPOINTS") - 1; 1624 bitmask |= LOG_WATCHPOINTS; 1625 } 1626 else if (strncmp (p, "LOG_STEP", sizeof ("LOG_STEP") - 1) == 0) 1627 { 1628 p += sizeof ("LOG_STEP") - 1; 1629 bitmask |= LOG_STEP; 1630 } 1631 else if (strncmp (p, "LOG_TASK", sizeof ("LOG_TASK") - 1) == 0) 1632 { 1633 p += sizeof ("LOG_TASK") - 1; 1634 bitmask |= LOG_TASK; 1635 } 1636 else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0) 1637 { 1638 p += sizeof ("LOG_ALL") - 1; 1639 bitmask |= LOG_ALL; 1640 } 1641 else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0) 1642 { 1643 p += sizeof ("LOG_DEFAULT") - 1; 1644 bitmask |= LOG_DEFAULT; 1645 } 1646 // end of auto-generated entries 1647 1648 else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0) 1649 { 1650 p += sizeof ("LOG_NONE") - 1; 1651 bitmask = 0; 1652 } 1653 else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0) 1654 { 1655 p += sizeof ("LOG_RNB_MINIMAL") - 1; 1656 bitmask |= LOG_RNB_MINIMAL; 1657 } 1658 else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0) 1659 { 1660 p += sizeof ("LOG_RNB_MEDIUM") - 1; 1661 bitmask |= LOG_RNB_MEDIUM; 1662 } 1663 else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0) 1664 { 1665 p += sizeof ("LOG_RNB_MAX") - 1; 1666 bitmask |= LOG_RNB_MAX; 1667 } 1668 else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0) 1669 { 1670 p += sizeof ("LOG_RNB_COMM") - 1; 1671 bitmask |= LOG_RNB_COMM; 1672 } 1673 else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0) 1674 { 1675 p += sizeof ("LOG_RNB_REMOTE") - 1; 1676 bitmask |= LOG_RNB_REMOTE; 1677 } 1678 else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0) 1679 { 1680 p += sizeof ("LOG_RNB_EVENTS") - 1; 1681 bitmask |= LOG_RNB_EVENTS; 1682 } 1683 else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0) 1684 { 1685 p += sizeof ("LOG_RNB_PROC") - 1; 1686 bitmask |= LOG_RNB_PROC; 1687 } 1688 else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0) 1689 { 1690 p += sizeof ("LOG_RNB_PACKETS") - 1; 1691 bitmask |= LOG_RNB_PACKETS; 1692 } 1693 else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0) 1694 { 1695 p += sizeof ("LOG_RNB_ALL") - 1; 1696 bitmask |= LOG_RNB_ALL; 1697 } 1698 else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0) 1699 { 1700 p += sizeof ("LOG_RNB_DEFAULT") - 1; 1701 bitmask |= LOG_RNB_DEFAULT; 1702 } 1703 else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0) 1704 { 1705 p += sizeof ("LOG_RNB_NONE") - 1; 1706 bitmask = 0; 1707 } 1708 else 1709 { 1710 /* Unrecognized logging bit; ignore it. */ 1711 const char *c = strchr (p, '|'); 1712 if (c) 1713 { 1714 p = c; 1715 } 1716 else 1717 { 1718 c = strchr (p, ';'); 1719 if (c) 1720 { 1721 p = c; 1722 } 1723 else 1724 { 1725 // Improperly terminated word; just go to end of str 1726 p = strchr (p, '\0'); 1727 } 1728 } 1729 } 1730 } 1731 // Did we get a properly formatted logging bitmask? 1732 if (p && *p == ';') 1733 { 1734 // Enable DNB logging 1735 DNBLogSetLogCallback(ASLLogCallback, NULL); 1736 DNBLogSetLogMask (bitmask); 1737 p++; 1738 } 1739 } 1740 // We're not going to support logging to a file for now. All logging 1741 // goes through ASL. 1742 #if 0 1743 else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0) 1744 { 1745 p += sizeof ("mode=") - 1; 1746 if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0) 1747 { 1748 DNBLogToASL (); 1749 p += sizeof ("asl;") - 1; 1750 } 1751 else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0) 1752 { 1753 DNBLogToFile (); 1754 p += sizeof ("file;") - 1; 1755 } 1756 else 1757 { 1758 // Ignore unknown argument 1759 const char *c = strchr (p, ';'); 1760 if (c) 1761 p = c + 1; 1762 else 1763 p = strchr (p, '\0'); 1764 } 1765 } 1766 else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0) 1767 { 1768 p += sizeof ("filename=") - 1; 1769 const char *c = strchr (p, ';'); 1770 if (c == NULL) 1771 { 1772 c = strchr (p, '\0'); 1773 continue; 1774 } 1775 char *fn = (char *) alloca (c - p + 1); 1776 strncpy (fn, p, c - p); 1777 fn[c - p] = '\0'; 1778 1779 // A file name of "asl" is special and is another way to indicate 1780 // that logging should be done via ASL, not by file. 1781 if (strcmp (fn, "asl") == 0) 1782 { 1783 DNBLogToASL (); 1784 } 1785 else 1786 { 1787 FILE *f = fopen (fn, "w"); 1788 if (f) 1789 { 1790 DNBLogSetLogFile (f); 1791 DNBEnableLogging (f, DNBLogGetLogMask ()); 1792 DNBLogToFile (); 1793 } 1794 } 1795 p = c + 1; 1796 } 1797 #endif /* #if 0 to enforce ASL logging only. */ 1798 else 1799 { 1800 // Ignore unknown argument 1801 const char *c = strchr (p, ';'); 1802 if (c) 1803 p = c + 1; 1804 else 1805 p = strchr (p, '\0'); 1806 } 1807 } 1808 1809 return rnb_success; 1810 } 1811 1812 rnb_err_t 1813 RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p) 1814 { 1815 m_thread_suffix_supported = true; 1816 return SendPacket ("OK"); 1817 } 1818 1819 rnb_err_t 1820 RNBRemote::HandlePacket_QStartNoAckMode (const char *p) 1821 { 1822 // Send the OK packet first so the correct checksum is appended... 1823 rnb_err_t result = SendPacket ("OK"); 1824 m_noack_mode = true; 1825 return result; 1826 } 1827 1828 1829 rnb_err_t 1830 RNBRemote::HandlePacket_QSetLogging (const char *p) 1831 { 1832 p += sizeof ("QSetLogging:") - 1; 1833 rnb_err_t result = set_logging (p); 1834 if (result == rnb_success) 1835 return SendPacket ("OK"); 1836 else 1837 return SendPacket ("E35"); 1838 } 1839 1840 rnb_err_t 1841 RNBRemote::HandlePacket_QSetDisableASLR (const char *p) 1842 { 1843 extern int g_disable_aslr; 1844 p += sizeof ("QSetDisableASLR:") - 1; 1845 switch (*p) 1846 { 1847 case '0': g_disable_aslr = 0; break; 1848 case '1': g_disable_aslr = 1; break; 1849 default: 1850 return SendPacket ("E56"); 1851 } 1852 return SendPacket ("OK"); 1853 } 1854 1855 rnb_err_t 1856 RNBRemote::HandlePacket_QSetSTDIO (const char *p) 1857 { 1858 // Only set stdin/out/err if we don't already have a process 1859 if (!m_ctx.HasValidProcessID()) 1860 { 1861 bool success = false; 1862 // Check the seventh character since the packet will be one of: 1863 // QSetSTDIN 1864 // QSetSTDOUT 1865 // QSetSTDERR 1866 StringExtractor packet(p); 1867 packet.SetFilePos (7); 1868 char ch = packet.GetChar(); 1869 while (packet.GetChar() != ':') 1870 /* Do nothing. */; 1871 1872 switch (ch) 1873 { 1874 case 'I': // STDIN 1875 packet.GetHexByteString (m_ctx.GetSTDIN()); 1876 success = !m_ctx.GetSTDIN().empty(); 1877 break; 1878 1879 case 'O': // STDOUT 1880 packet.GetHexByteString (m_ctx.GetSTDOUT()); 1881 success = !m_ctx.GetSTDOUT().empty(); 1882 break; 1883 1884 case 'E': // STDERR 1885 packet.GetHexByteString (m_ctx.GetSTDERR()); 1886 success = !m_ctx.GetSTDERR().empty(); 1887 break; 1888 1889 default: 1890 break; 1891 } 1892 if (success) 1893 return SendPacket ("OK"); 1894 return SendPacket ("E57"); 1895 } 1896 return SendPacket ("E58"); 1897 } 1898 1899 rnb_err_t 1900 RNBRemote::HandlePacket_QSetWorkingDir (const char *p) 1901 { 1902 // Only set the working directory if we don't already have a process 1903 if (!m_ctx.HasValidProcessID()) 1904 { 1905 StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1); 1906 if (packet.GetHexByteString (m_ctx.GetWorkingDir())) 1907 { 1908 struct stat working_dir_stat; 1909 if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1) 1910 { 1911 m_ctx.GetWorkingDir().clear(); 1912 return SendPacket ("E61"); // Working directory doesn't exist... 1913 } 1914 else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR) 1915 { 1916 return SendPacket ("OK"); 1917 } 1918 else 1919 { 1920 m_ctx.GetWorkingDir().clear(); 1921 return SendPacket ("E62"); // Working directory isn't a directory... 1922 } 1923 } 1924 return SendPacket ("E59"); // Invalid path 1925 } 1926 return SendPacket ("E60"); // Already had a process, too late to set working dir 1927 } 1928 1929 rnb_err_t 1930 RNBRemote::HandlePacket_QSyncThreadState (const char *p) 1931 { 1932 if (!m_ctx.HasValidProcessID()) 1933 { 1934 // We allow gdb to connect to a server that hasn't started running 1935 // the target yet. gdb still wants to ask questions about it and 1936 // freaks out if it gets an error. So just return OK here. 1937 return SendPacket ("OK"); 1938 } 1939 1940 errno = 0; 1941 p += strlen("QSyncThreadState:"); 1942 nub_thread_t tid = strtoul (p, NULL, 16); 1943 if (errno != 0 && tid == 0) 1944 { 1945 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in QSyncThreadState packet"); 1946 } 1947 if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid)) 1948 return SendPacket("OK"); 1949 else 1950 return SendPacket ("E61"); 1951 } 1952 1953 rnb_err_t 1954 RNBRemote::HandlePacket_QListThreadsInStopReply (const char *p) 1955 { 1956 // If this packet is received, it allows us to send an extra key/value 1957 // pair in the stop reply packets where we will list all of the thread IDs 1958 // separated by commas: 1959 // 1960 // "threads:10a,10b,10c;" 1961 // 1962 // This will get included in the stop reply packet as something like: 1963 // 1964 // "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;" 1965 // 1966 // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and 1967 // speed things up a bit. 1968 // 1969 // Send the OK packet first so the correct checksum is appended... 1970 rnb_err_t result = SendPacket ("OK"); 1971 m_list_threads_in_stop_reply = true; 1972 return result; 1973 } 1974 1975 1976 rnb_err_t 1977 RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p) 1978 { 1979 /* The number of characters in a packet payload that gdb is 1980 prepared to accept. The packet-start char, packet-end char, 1981 2 checksum chars and terminating null character are not included 1982 in this size. */ 1983 p += sizeof ("QSetMaxPayloadSize:") - 1; 1984 errno = 0; 1985 uint32_t size = strtoul (p, NULL, 16); 1986 if (errno != 0 && size == 0) 1987 { 1988 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet"); 1989 } 1990 m_max_payload_size = size; 1991 return SendPacket ("OK"); 1992 } 1993 1994 rnb_err_t 1995 RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p) 1996 { 1997 /* This tells us the largest packet that gdb can handle. 1998 i.e. the size of gdb's packet-reading buffer. 1999 QSetMaxPayloadSize is preferred because it is less ambiguous. */ 2000 p += sizeof ("QSetMaxPacketSize:") - 1; 2001 errno = 0; 2002 uint32_t size = strtoul (p, NULL, 16); 2003 if (errno != 0 && size == 0) 2004 { 2005 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet"); 2006 } 2007 m_max_payload_size = size - 5; 2008 return SendPacket ("OK"); 2009 } 2010 2011 2012 2013 2014 rnb_err_t 2015 RNBRemote::HandlePacket_QEnvironment (const char *p) 2016 { 2017 /* This sets the environment for the target program. The packet is of the form: 2018 2019 QEnvironment:VARIABLE=VALUE 2020 2021 */ 2022 2023 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"", 2024 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2025 2026 p += sizeof ("QEnvironment:") - 1; 2027 RNBContext& ctx = Context(); 2028 2029 ctx.PushEnvironment (p); 2030 return SendPacket ("OK"); 2031 } 2032 2033 rnb_err_t 2034 RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p) 2035 { 2036 /* This sets the environment for the target program. The packet is of the form: 2037 2038 QEnvironmentHexEncoded:VARIABLE=VALUE 2039 2040 The VARIABLE=VALUE part is sent hex-encoded so chracters like '#' with special 2041 meaning in the remote protocol won't break it. 2042 */ 2043 2044 DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"", 2045 (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p); 2046 2047 p += sizeof ("QEnvironmentHexEncoded:") - 1; 2048 2049 std::string arg; 2050 const char *c; 2051 c = p; 2052 while (*c != '\0') 2053 { 2054 if (*(c + 1) == '\0') 2055 { 2056 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2057 } 2058 char smallbuf[3]; 2059 smallbuf[0] = *c; 2060 smallbuf[1] = *(c + 1); 2061 smallbuf[2] = '\0'; 2062 errno = 0; 2063 int ch = strtoul (smallbuf, NULL, 16); 2064 if (errno != 0 && ch == 0) 2065 { 2066 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt"); 2067 } 2068 arg.push_back(ch); 2069 c += 2; 2070 } 2071 2072 RNBContext& ctx = Context(); 2073 if (arg.length() > 0) 2074 ctx.PushEnvironment (arg.c_str()); 2075 2076 return SendPacket ("OK"); 2077 } 2078 2079 2080 rnb_err_t 2081 RNBRemote::HandlePacket_QLaunchArch (const char *p) 2082 { 2083 p += sizeof ("QLaunchArch:") - 1; 2084 if (DNBSetArchitecture(p)) 2085 return SendPacket ("OK"); 2086 return SendPacket ("E63"); 2087 } 2088 2089 void 2090 append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap) 2091 { 2092 int i; 2093 if (swap) 2094 { 2095 for (i = buf_size-1; i >= 0; i--) 2096 ostrm << RAWHEX8(buf[i]); 2097 } 2098 else 2099 { 2100 for (i = 0; i < buf_size; i++) 2101 ostrm << RAWHEX8(buf[i]); 2102 } 2103 } 2104 2105 2106 void 2107 register_value_in_hex_fixed_width (std::ostream& ostrm, 2108 nub_process_t pid, 2109 nub_thread_t tid, 2110 const register_map_entry_t* reg, 2111 const DNBRegisterValue *reg_value_ptr) 2112 { 2113 if (reg != NULL) 2114 { 2115 DNBRegisterValue reg_value; 2116 if (reg_value_ptr == NULL) 2117 { 2118 if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, ®_value)) 2119 reg_value_ptr = ®_value; 2120 } 2121 2122 if (reg_value_ptr) 2123 { 2124 append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size, false); 2125 } 2126 else 2127 { 2128 // If we fail to read a regiser value, check if it has a default 2129 // fail value. If it does, return this instead in case some of 2130 // the registers are not available on the current system. 2131 if (reg->nub_info.size > 0) 2132 { 2133 std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0'); 2134 append_hex_value (ostrm, zeros.data(), zeros.size(), false); 2135 } 2136 } 2137 } 2138 } 2139 2140 2141 void 2142 gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm, 2143 nub_process_t pid, 2144 nub_thread_t tid, 2145 const register_map_entry_t* reg, 2146 const DNBRegisterValue *reg_value_ptr) 2147 { 2148 // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX 2149 // gdb register number, and VVVVVVVV is the correct number of hex bytes 2150 // as ASCII for the register value. 2151 if (reg != NULL) 2152 { 2153 ostrm << RAWHEX8(reg->gdb_regnum) << ':'; 2154 register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr); 2155 ostrm << ';'; 2156 } 2157 } 2158 2159 rnb_err_t 2160 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) 2161 { 2162 const nub_process_t pid = m_ctx.ProcessID(); 2163 if (pid == INVALID_NUB_PROCESS) 2164 return SendPacket("E50"); 2165 2166 struct DNBThreadStopInfo tid_stop_info; 2167 2168 /* Fill the remaining space in this packet with as many registers 2169 as we can stuff in there. */ 2170 2171 if (DNBThreadGetStopReason (pid, tid, &tid_stop_info)) 2172 { 2173 const bool did_exec = tid_stop_info.reason == eStopTypeExec; 2174 if (did_exec) 2175 RNBRemote::InitializeRegisters(true); 2176 2177 std::ostringstream ostrm; 2178 // Output the T packet with the thread 2179 ostrm << 'T'; 2180 int signum = tid_stop_info.details.signal.signo; 2181 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); 2182 2183 // Translate any mach exceptions to gdb versions, unless they are 2184 // common exceptions like a breakpoint or a soft signal. 2185 switch (tid_stop_info.details.exception.type) 2186 { 2187 default: signum = 0; break; 2188 case EXC_BREAKPOINT: signum = SIGTRAP; break; 2189 case EXC_BAD_ACCESS: signum = TARGET_EXC_BAD_ACCESS; break; 2190 case EXC_BAD_INSTRUCTION: signum = TARGET_EXC_BAD_INSTRUCTION; break; 2191 case EXC_ARITHMETIC: signum = TARGET_EXC_ARITHMETIC; break; 2192 case EXC_EMULATION: signum = TARGET_EXC_EMULATION; break; 2193 case EXC_SOFTWARE: 2194 if (tid_stop_info.details.exception.data_count == 2 && 2195 tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL) 2196 signum = tid_stop_info.details.exception.data[1]; 2197 else 2198 signum = TARGET_EXC_SOFTWARE; 2199 break; 2200 } 2201 2202 ostrm << RAWHEX8(signum & 0xff); 2203 2204 ostrm << std::hex << "thread:" << tid << ';'; 2205 2206 const char *thread_name = DNBThreadGetName (pid, tid); 2207 if (thread_name && thread_name[0]) 2208 { 2209 size_t thread_name_len = strlen(thread_name); 2210 2211 if (::strcspn (thread_name, "$#+-;:") == thread_name_len) 2212 ostrm << std::hex << "name:" << thread_name << ';'; 2213 else 2214 { 2215 // the thread name contains special chars, send as hex bytes 2216 ostrm << std::hex << "hexname:"; 2217 uint8_t *u_thread_name = (uint8_t *)thread_name; 2218 for (int i = 0; i < thread_name_len; i++) 2219 ostrm << RAWHEX8(u_thread_name[i]); 2220 ostrm << ';'; 2221 } 2222 } 2223 2224 thread_identifier_info_data_t thread_ident_info; 2225 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info)) 2226 { 2227 if (thread_ident_info.dispatch_qaddr != 0) 2228 ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';'; 2229 } 2230 2231 // If a 'QListThreadsInStopReply' was sent to enable this feature, we 2232 // will send all thread IDs back in the "threads" key whose value is 2233 // a listc of hex thread IDs separated by commas: 2234 // "threads:10a,10b,10c;" 2235 // This will save the debugger from having to send a pair of qfThreadInfo 2236 // and qsThreadInfo packets, but it also might take a lot of room in the 2237 // stop reply packet, so it must be enabled only on systems where there 2238 // are no limits on packet lengths. 2239 2240 if (m_list_threads_in_stop_reply) 2241 { 2242 const nub_size_t numthreads = DNBProcessGetNumThreads (pid); 2243 if (numthreads > 0) 2244 { 2245 ostrm << std::hex << "threads:"; 2246 for (nub_size_t i = 0; i < numthreads; ++i) 2247 { 2248 nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i); 2249 if (i > 0) 2250 ostrm << ','; 2251 ostrm << std::hex << th; 2252 } 2253 ostrm << ';'; 2254 } 2255 } 2256 2257 if (g_num_reg_entries == 0) 2258 InitializeRegisters (); 2259 2260 if (g_reg_entries != NULL) 2261 { 2262 DNBRegisterValue reg_value; 2263 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++) 2264 { 2265 // Expedite all registers in the first register set that aren't 2266 // contained in other registers 2267 if (g_reg_entries[reg].nub_info.set == 1 && 2268 g_reg_entries[reg].nub_info.value_regs == NULL) 2269 { 2270 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, ®_value)) 2271 continue; 2272 2273 gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], ®_value); 2274 } 2275 } 2276 } 2277 2278 if (did_exec) 2279 { 2280 ostrm << "reason:exec;"; 2281 } 2282 else if (tid_stop_info.details.exception.type) 2283 { 2284 ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";"; 2285 ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";"; 2286 for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i) 2287 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";"; 2288 } 2289 return SendPacket (ostrm.str ()); 2290 } 2291 return SendPacket("E51"); 2292 } 2293 2294 /* '?' 2295 The stop reply packet - tell gdb what the status of the inferior is. 2296 Often called the questionmark_packet. */ 2297 2298 rnb_err_t 2299 RNBRemote::HandlePacket_last_signal (const char *unused) 2300 { 2301 if (!m_ctx.HasValidProcessID()) 2302 { 2303 // Inferior is not yet specified/running 2304 return SendPacket ("E02"); 2305 } 2306 2307 nub_process_t pid = m_ctx.ProcessID(); 2308 nub_state_t pid_state = DNBProcessGetState (pid); 2309 2310 switch (pid_state) 2311 { 2312 case eStateAttaching: 2313 case eStateLaunching: 2314 case eStateRunning: 2315 case eStateStepping: 2316 case eStateDetached: 2317 return rnb_success; // Ignore 2318 2319 case eStateSuspended: 2320 case eStateStopped: 2321 case eStateCrashed: 2322 { 2323 nub_thread_t tid = DNBProcessGetCurrentThread (pid); 2324 // Make sure we set the current thread so g and p packets return 2325 // the data the gdb will expect. 2326 SetCurrentThread (tid); 2327 2328 SendStopReplyPacketForThread (tid); 2329 } 2330 break; 2331 2332 case eStateInvalid: 2333 case eStateUnloaded: 2334 case eStateExited: 2335 { 2336 char pid_exited_packet[16] = ""; 2337 int pid_status = 0; 2338 // Process exited with exit status 2339 if (!DNBProcessGetExitStatus(pid, &pid_status)) 2340 pid_status = 0; 2341 2342 if (pid_status) 2343 { 2344 if (WIFEXITED (pid_status)) 2345 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status)); 2346 else if (WIFSIGNALED (pid_status)) 2347 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status)); 2348 else if (WIFSTOPPED (pid_status)) 2349 snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status)); 2350 } 2351 2352 // If we have an empty exit packet, lets fill one in to be safe. 2353 if (!pid_exited_packet[0]) 2354 { 2355 strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1); 2356 pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0'; 2357 } 2358 2359 return SendPacket (pid_exited_packet); 2360 } 2361 break; 2362 } 2363 return rnb_success; 2364 } 2365 2366 rnb_err_t 2367 RNBRemote::HandlePacket_M (const char *p) 2368 { 2369 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2370 { 2371 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet"); 2372 } 2373 2374 char *c; 2375 p++; 2376 errno = 0; 2377 nub_addr_t addr = strtoull (p, &c, 16); 2378 if (errno != 0 && addr == 0) 2379 { 2380 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet"); 2381 } 2382 if (*c != ',') 2383 { 2384 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet"); 2385 } 2386 2387 /* Advance 'p' to the length part of the packet. */ 2388 p += (c - p) + 1; 2389 2390 errno = 0; 2391 uint32_t length = strtoul (p, &c, 16); 2392 if (errno != 0 && length == 0) 2393 { 2394 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet"); 2395 } 2396 if (length == 0) 2397 { 2398 return SendPacket ("OK"); 2399 } 2400 2401 if (*c != ':') 2402 { 2403 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet"); 2404 } 2405 /* Advance 'p' to the data part of the packet. */ 2406 p += (c - p) + 1; 2407 2408 int datalen = strlen (p); 2409 if (datalen & 0x1) 2410 { 2411 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet"); 2412 } 2413 if (datalen == 0) 2414 { 2415 return SendPacket ("OK"); 2416 } 2417 2418 uint8_t *buf = (uint8_t *) alloca (datalen / 2); 2419 uint8_t *i = buf; 2420 2421 while (*p != '\0' && *(p + 1) != '\0') 2422 { 2423 char hexbuf[3]; 2424 hexbuf[0] = *p; 2425 hexbuf[1] = *(p + 1); 2426 hexbuf[2] = '\0'; 2427 errno = 0; 2428 uint8_t byte = strtoul (hexbuf, NULL, 16); 2429 if (errno != 0 && byte == 0) 2430 { 2431 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet"); 2432 } 2433 *i++ = byte; 2434 p += 2; 2435 } 2436 2437 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf); 2438 if (wrote != length) 2439 return SendPacket ("E09"); 2440 else 2441 return SendPacket ("OK"); 2442 } 2443 2444 2445 rnb_err_t 2446 RNBRemote::HandlePacket_m (const char *p) 2447 { 2448 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2449 { 2450 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet"); 2451 } 2452 2453 char *c; 2454 p++; 2455 errno = 0; 2456 nub_addr_t addr = strtoull (p, &c, 16); 2457 if (errno != 0 && addr == 0) 2458 { 2459 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet"); 2460 } 2461 if (*c != ',') 2462 { 2463 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet"); 2464 } 2465 2466 /* Advance 'p' to the length part of the packet. */ 2467 p += (c - p) + 1; 2468 2469 errno = 0; 2470 uint32_t length = strtoul (p, NULL, 16); 2471 if (errno != 0 && length == 0) 2472 { 2473 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 2474 } 2475 if (length == 0) 2476 { 2477 return SendPacket (""); 2478 } 2479 2480 uint8_t buf[length]; 2481 int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, length, buf); 2482 if (bytes_read == 0) 2483 { 2484 return SendPacket ("E08"); 2485 } 2486 2487 // "The reply may contain fewer bytes than requested if the server was able 2488 // to read only part of the region of memory." 2489 length = bytes_read; 2490 2491 std::ostringstream ostrm; 2492 for (int i = 0; i < length; i++) 2493 ostrm << RAWHEX8(buf[i]); 2494 return SendPacket (ostrm.str ()); 2495 } 2496 2497 rnb_err_t 2498 RNBRemote::HandlePacket_X (const char *p) 2499 { 2500 if (p == NULL || p[0] == '\0' || strlen (p) < 3) 2501 { 2502 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet"); 2503 } 2504 2505 char *c; 2506 p++; 2507 errno = 0; 2508 nub_addr_t addr = strtoull (p, &c, 16); 2509 if (errno != 0 && addr == 0) 2510 { 2511 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet"); 2512 } 2513 if (*c != ',') 2514 { 2515 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet"); 2516 } 2517 2518 /* Advance 'p' to the length part of the packet. */ 2519 p += (c - p) + 1; 2520 2521 errno = 0; 2522 int length = strtoul (p, NULL, 16); 2523 if (errno != 0 && length == 0) 2524 { 2525 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet"); 2526 } 2527 2528 // I think gdb sends a zero length write request to test whether this 2529 // packet is accepted. 2530 if (length == 0) 2531 { 2532 return SendPacket ("OK"); 2533 } 2534 2535 std::vector<uint8_t> data = decode_binary_data (c, -1); 2536 std::vector<uint8_t>::const_iterator it; 2537 uint8_t *buf = (uint8_t *) alloca (data.size ()); 2538 uint8_t *i = buf; 2539 for (it = data.begin (); it != data.end (); ++it) 2540 { 2541 *i++ = *it; 2542 } 2543 2544 nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf); 2545 if (wrote != data.size ()) 2546 return SendPacket ("E08"); 2547 return SendPacket ("OK"); 2548 } 2549 2550 /* 'g' -- read registers 2551 Get the contents of the registers for the current thread, 2552 send them to gdb. 2553 Should the setting of the Hg packet determine which thread's registers 2554 are returned? */ 2555 2556 rnb_err_t 2557 RNBRemote::HandlePacket_g (const char *p) 2558 { 2559 std::ostringstream ostrm; 2560 if (!m_ctx.HasValidProcessID()) 2561 { 2562 return SendPacket ("E11"); 2563 } 2564 2565 if (g_num_reg_entries == 0) 2566 InitializeRegisters (); 2567 2568 nub_process_t pid = m_ctx.ProcessID (); 2569 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1); 2570 if (tid == INVALID_NUB_THREAD) 2571 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 2572 2573 // Get the register context size first by calling with NULL buffer 2574 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 2575 if (reg_ctx_size) 2576 { 2577 // Now allocate enough space for the entire register context 2578 std::vector<uint8_t> reg_ctx; 2579 reg_ctx.resize(reg_ctx_size); 2580 // Now read the register context 2581 reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, ®_ctx[0], reg_ctx.size()); 2582 if (reg_ctx_size) 2583 { 2584 append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false); 2585 return SendPacket (ostrm.str ()); 2586 } 2587 } 2588 return SendPacket ("E74"); 2589 } 2590 2591 /* 'G XXX...' -- write registers 2592 How is the thread for these specified, beyond "the current thread"? 2593 Does gdb actually use the Hg packet to set this? */ 2594 2595 rnb_err_t 2596 RNBRemote::HandlePacket_G (const char *p) 2597 { 2598 if (!m_ctx.HasValidProcessID()) 2599 { 2600 return SendPacket ("E11"); 2601 } 2602 2603 if (g_num_reg_entries == 0) 2604 InitializeRegisters (); 2605 2606 StringExtractor packet(p); 2607 packet.SetFilePos(1); // Skip the 'G' 2608 2609 nub_process_t pid = m_ctx.ProcessID(); 2610 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 2611 if (tid == INVALID_NUB_THREAD) 2612 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 2613 2614 // Get the register context size first by calling with NULL buffer 2615 nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0); 2616 if (reg_ctx_size) 2617 { 2618 // Now allocate enough space for the entire register context 2619 std::vector<uint8_t> reg_ctx; 2620 reg_ctx.resize(reg_ctx_size); 2621 2622 const nub_size_t bytes_extracted = packet.GetHexBytes (®_ctx[0], reg_ctx.size(), 0xcc); 2623 if (bytes_extracted == reg_ctx.size()) 2624 { 2625 // Now write the register context 2626 reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size()); 2627 if (reg_ctx_size == reg_ctx.size()) 2628 return SendPacket ("OK"); 2629 else 2630 return SendPacket ("E55"); 2631 } 2632 else 2633 { 2634 DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size); 2635 return SendPacket ("E64"); 2636 } 2637 } 2638 return SendPacket ("E65"); 2639 } 2640 2641 static bool 2642 RNBRemoteShouldCancelCallback (void *not_used) 2643 { 2644 RNBRemoteSP remoteSP(g_remoteSP); 2645 if (remoteSP.get() != NULL) 2646 { 2647 RNBRemote* remote = remoteSP.get(); 2648 if (remote->Comm().IsConnected()) 2649 return false; 2650 else 2651 return true; 2652 } 2653 return true; 2654 } 2655 2656 2657 // FORMAT: _MXXXXXX,PPP 2658 // XXXXXX: big endian hex chars 2659 // PPP: permissions can be any combo of r w x chars 2660 // 2661 // RESPONSE: XXXXXX 2662 // XXXXXX: hex address of the newly allocated memory 2663 // EXX: error code 2664 // 2665 // EXAMPLES: 2666 // _M123000,rw 2667 // _M123000,rwx 2668 // _M123000,xw 2669 2670 rnb_err_t 2671 RNBRemote::HandlePacket_AllocateMemory (const char *p) 2672 { 2673 StringExtractor packet (p); 2674 packet.SetFilePos(2); // Skip the "_M" 2675 2676 nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0); 2677 if (size != 0) 2678 { 2679 if (packet.GetChar() == ',') 2680 { 2681 uint32_t permissions = 0; 2682 char ch; 2683 bool success = true; 2684 while (success && (ch = packet.GetChar()) != '\0') 2685 { 2686 switch (ch) 2687 { 2688 case 'r': permissions |= eMemoryPermissionsReadable; break; 2689 case 'w': permissions |= eMemoryPermissionsWritable; break; 2690 case 'x': permissions |= eMemoryPermissionsExecutable; break; 2691 default: success = false; break; 2692 } 2693 } 2694 2695 if (success) 2696 { 2697 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions); 2698 if (addr != INVALID_NUB_ADDRESS) 2699 { 2700 std::ostringstream ostrm; 2701 ostrm << RAW_HEXBASE << addr; 2702 return SendPacket (ostrm.str ()); 2703 } 2704 } 2705 } 2706 } 2707 return SendPacket ("E53"); 2708 } 2709 2710 // FORMAT: _mXXXXXX 2711 // XXXXXX: address that was previosly allocated 2712 // 2713 // RESPONSE: XXXXXX 2714 // OK: address was deallocated 2715 // EXX: error code 2716 // 2717 // EXAMPLES: 2718 // _m123000 2719 2720 rnb_err_t 2721 RNBRemote::HandlePacket_DeallocateMemory (const char *p) 2722 { 2723 StringExtractor packet (p); 2724 packet.SetFilePos(2); // Skip the "_m" 2725 nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS); 2726 2727 if (addr != INVALID_NUB_ADDRESS) 2728 { 2729 if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr)) 2730 return SendPacket ("OK"); 2731 } 2732 return SendPacket ("E54"); 2733 } 2734 2735 2736 // FORMAT: QSaveRegisterState;thread:TTTT; (when thread suffix is supported) 2737 // FORMAT: QSaveRegisterState (when thread suffix is NOT supported) 2738 // TTTT: thread ID in hex 2739 // 2740 // RESPONSE: 2741 // SAVEID: Where SAVEID is a decimal number that represents the save ID 2742 // that can be passed back into a "QRestoreRegisterState" packet 2743 // EXX: error code 2744 // 2745 // EXAMPLES: 2746 // QSaveRegisterState;thread:1E34; (when thread suffix is supported) 2747 // QSaveRegisterState (when thread suffix is NOT supported) 2748 2749 rnb_err_t 2750 RNBRemote::HandlePacket_SaveRegisterState (const char *p) 2751 { 2752 nub_process_t pid = m_ctx.ProcessID (); 2753 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 2754 if (tid == INVALID_NUB_THREAD) 2755 { 2756 if (m_thread_suffix_supported) 2757 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 2758 else 2759 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 2760 } 2761 2762 // Get the register context size first by calling with NULL buffer 2763 const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid); 2764 if (save_id != 0) 2765 { 2766 char response[64]; 2767 snprintf (response, sizeof(response), "%u", save_id); 2768 return SendPacket (response); 2769 } 2770 else 2771 { 2772 return SendPacket ("E75"); 2773 } 2774 } 2775 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT; (when thread suffix is supported) 2776 // FORMAT: QRestoreRegisterState:SAVEID (when thread suffix is NOT supported) 2777 // TTTT: thread ID in hex 2778 // SAVEID: a decimal number that represents the save ID that was 2779 // returned from a call to "QSaveRegisterState" 2780 // 2781 // RESPONSE: 2782 // OK: successfully restored registers for the specified thread 2783 // EXX: error code 2784 // 2785 // EXAMPLES: 2786 // QRestoreRegisterState:1;thread:1E34; (when thread suffix is supported) 2787 // QRestoreRegisterState:1 (when thread suffix is NOT supported) 2788 2789 rnb_err_t 2790 RNBRemote::HandlePacket_RestoreRegisterState (const char *p) 2791 { 2792 nub_process_t pid = m_ctx.ProcessID (); 2793 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 2794 if (tid == INVALID_NUB_THREAD) 2795 { 2796 if (m_thread_suffix_supported) 2797 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet"); 2798 else 2799 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet"); 2800 } 2801 2802 StringExtractor packet (p); 2803 packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:" 2804 const uint32_t save_id = packet.GetU32(0); 2805 2806 if (save_id != 0) 2807 { 2808 // Get the register context size first by calling with NULL buffer 2809 if (DNBThreadRestoreRegisterState(pid, tid, save_id)) 2810 return SendPacket ("OK"); 2811 else 2812 return SendPacket ("E77"); 2813 } 2814 return SendPacket ("E76"); 2815 } 2816 2817 static bool 2818 GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name) 2819 { 2820 bool return_val = true; 2821 while (*p != '\0') 2822 { 2823 char smallbuf[3]; 2824 smallbuf[0] = *p; 2825 smallbuf[1] = *(p + 1); 2826 smallbuf[2] = '\0'; 2827 2828 errno = 0; 2829 int ch = strtoul (smallbuf, NULL, 16); 2830 if (errno != 0 && ch == 0) 2831 { 2832 return_val = false; 2833 break; 2834 } 2835 2836 attach_name.push_back(ch); 2837 p += 2; 2838 } 2839 return return_val; 2840 } 2841 2842 /* 2843 vAttach;pid 2844 2845 Attach to a new process with the specified process ID. pid is a hexadecimal integer 2846 identifying the process. If the stub is currently controlling a process, it is 2847 killed. The attached process is stopped.This packet is only available in extended 2848 mode (see extended mode). 2849 2850 Reply: 2851 "ENN" for an error 2852 "Any Stop Reply Packet" for success 2853 */ 2854 2855 rnb_err_t 2856 RNBRemote::HandlePacket_v (const char *p) 2857 { 2858 if (strcmp (p, "vCont;c") == 0) 2859 { 2860 // Simple continue 2861 return RNBRemote::HandlePacket_c("c"); 2862 } 2863 else if (strcmp (p, "vCont;s") == 0) 2864 { 2865 // Simple step 2866 return RNBRemote::HandlePacket_s("s"); 2867 } 2868 else if (strstr (p, "vCont") == p) 2869 { 2870 typedef struct 2871 { 2872 nub_thread_t tid; 2873 char action; 2874 int signal; 2875 } vcont_action_t; 2876 2877 DNBThreadResumeActions thread_actions; 2878 char *c = (char *)(p += strlen("vCont")); 2879 char *c_end = c + strlen(c); 2880 if (*c == '?') 2881 return SendPacket ("vCont;c;C;s;S"); 2882 2883 while (c < c_end && *c == ';') 2884 { 2885 ++c; // Skip the semi-colon 2886 DNBThreadResumeAction thread_action; 2887 thread_action.tid = INVALID_NUB_THREAD; 2888 thread_action.state = eStateInvalid; 2889 thread_action.signal = 0; 2890 thread_action.addr = INVALID_NUB_ADDRESS; 2891 2892 char action = *c++; 2893 2894 switch (action) 2895 { 2896 case 'C': 2897 errno = 0; 2898 thread_action.signal = strtoul (c, &c, 16); 2899 if (errno != 0) 2900 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 2901 // Fall through to next case... 2902 2903 case 'c': 2904 // Continue 2905 thread_action.state = eStateRunning; 2906 break; 2907 2908 case 'S': 2909 errno = 0; 2910 thread_action.signal = strtoul (c, &c, 16); 2911 if (errno != 0) 2912 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet"); 2913 // Fall through to next case... 2914 2915 case 's': 2916 // Step 2917 thread_action.state = eStateStepping; 2918 break; 2919 2920 default: 2921 HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet"); 2922 break; 2923 } 2924 if (*c == ':') 2925 { 2926 errno = 0; 2927 thread_action.tid = strtoul (++c, &c, 16); 2928 if (errno != 0) 2929 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet"); 2930 } 2931 2932 thread_actions.Append (thread_action); 2933 } 2934 2935 // If a default action for all other threads wasn't mentioned 2936 // then we should stop the threads 2937 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 2938 DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize()); 2939 return rnb_success; 2940 } 2941 else if (strstr (p, "vAttach") == p) 2942 { 2943 nub_process_t attach_pid = INVALID_NUB_PROCESS; 2944 char err_str[1024]={'\0'}; 2945 2946 if (strstr (p, "vAttachWait;") == p) 2947 { 2948 p += strlen("vAttachWait;"); 2949 std::string attach_name; 2950 if (!GetProcessNameFrom_vAttach(p, attach_name)) 2951 { 2952 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt"); 2953 } 2954 const bool ignore_existing = true; 2955 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 2956 2957 } 2958 else if (strstr (p, "vAttachOrWait;") == p) 2959 { 2960 p += strlen("vAttachOrWait;"); 2961 std::string attach_name; 2962 if (!GetProcessNameFrom_vAttach(p, attach_name)) 2963 { 2964 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt"); 2965 } 2966 const bool ignore_existing = false; 2967 attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback); 2968 } 2969 else if (strstr (p, "vAttachName;") == p) 2970 { 2971 p += strlen("vAttachName;"); 2972 std::string attach_name; 2973 if (!GetProcessNameFrom_vAttach(p, attach_name)) 2974 { 2975 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt"); 2976 } 2977 2978 attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str)); 2979 2980 } 2981 else if (strstr (p, "vAttach;") == p) 2982 { 2983 p += strlen("vAttach;"); 2984 char *end = NULL; 2985 attach_pid = strtoul (p, &end, 16); // PID will be in hex, so use base 16 to decode 2986 if (p != end && *end == '\0') 2987 { 2988 // Wait at most 30 second for attach 2989 struct timespec attach_timeout_abstime; 2990 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0); 2991 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str)); 2992 } 2993 } 2994 else 2995 { 2996 return HandlePacket_UNIMPLEMENTED(p); 2997 } 2998 2999 3000 if (attach_pid != INVALID_NUB_PROCESS) 3001 { 3002 if (m_ctx.ProcessID() != attach_pid) 3003 m_ctx.SetProcessID(attach_pid); 3004 // Send a stop reply packet to indicate we successfully attached! 3005 NotifyThatProcessStopped (); 3006 return rnb_success; 3007 } 3008 else 3009 { 3010 m_ctx.LaunchStatus().SetError(-1, DNBError::Generic); 3011 if (err_str[0]) 3012 m_ctx.LaunchStatus().SetErrorString(err_str); 3013 else 3014 m_ctx.LaunchStatus().SetErrorString("attach failed"); 3015 return SendPacket ("E01"); // E01 is our magic error value for attach failed. 3016 } 3017 } 3018 3019 // All other failures come through here 3020 return HandlePacket_UNIMPLEMENTED(p); 3021 } 3022 3023 /* 'T XX' -- status of thread 3024 Check if the specified thread is alive. 3025 The thread number is in hex? */ 3026 3027 rnb_err_t 3028 RNBRemote::HandlePacket_T (const char *p) 3029 { 3030 p++; 3031 if (p == NULL || *p == '\0') 3032 { 3033 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet"); 3034 } 3035 if (!m_ctx.HasValidProcessID()) 3036 { 3037 return SendPacket ("E15"); 3038 } 3039 errno = 0; 3040 nub_thread_t tid = strtoul (p, NULL, 16); 3041 if (errno != 0 && tid == 0) 3042 { 3043 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet"); 3044 } 3045 3046 nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid); 3047 if (state == eStateInvalid || state == eStateExited || state == eStateCrashed) 3048 { 3049 return SendPacket ("E16"); 3050 } 3051 3052 return SendPacket ("OK"); 3053 } 3054 3055 3056 rnb_err_t 3057 RNBRemote::HandlePacket_z (const char *p) 3058 { 3059 if (p == NULL || *p == '\0') 3060 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet"); 3061 3062 if (!m_ctx.HasValidProcessID()) 3063 return SendPacket ("E15"); 3064 3065 char packet_cmd = *p++; 3066 char break_type = *p++; 3067 3068 if (*p++ != ',') 3069 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3070 3071 char *c = NULL; 3072 nub_process_t pid = m_ctx.ProcessID(); 3073 errno = 0; 3074 nub_addr_t addr = strtoull (p, &c, 16); 3075 if (errno != 0 && addr == 0) 3076 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet"); 3077 p = c; 3078 if (*p++ != ',') 3079 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet"); 3080 3081 errno = 0; 3082 uint32_t byte_size = strtoul (p, &c, 16); 3083 if (errno != 0 && byte_size == 0) 3084 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet"); 3085 3086 if (packet_cmd == 'Z') 3087 { 3088 // set 3089 switch (break_type) 3090 { 3091 case '0': // set software breakpoint 3092 case '1': // set hardware breakpoint 3093 { 3094 // gdb can send multiple Z packets for the same address and 3095 // these calls must be ref counted. 3096 bool hardware = (break_type == '1'); 3097 3098 if (DNBBreakpointSet (pid, addr, byte_size, hardware)) 3099 { 3100 // We successfully created a breakpoint, now lets full out 3101 // a ref count structure with the breakID and add it to our 3102 // map. 3103 return SendPacket ("OK"); 3104 } 3105 else 3106 { 3107 // We failed to set the software breakpoint 3108 return SendPacket ("E09"); 3109 } 3110 } 3111 break; 3112 3113 case '2': // set write watchpoint 3114 case '3': // set read watchpoint 3115 case '4': // set access watchpoint 3116 { 3117 bool hardware = true; 3118 uint32_t watch_flags = 0; 3119 if (break_type == '2') 3120 watch_flags = WATCH_TYPE_WRITE; 3121 else if (break_type == '3') 3122 watch_flags = WATCH_TYPE_READ; 3123 else 3124 watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE; 3125 3126 if (DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware)) 3127 { 3128 return SendPacket ("OK"); 3129 } 3130 else 3131 { 3132 // We failed to set the watchpoint 3133 return SendPacket ("E09"); 3134 } 3135 } 3136 break; 3137 3138 default: 3139 break; 3140 } 3141 } 3142 else if (packet_cmd == 'z') 3143 { 3144 // remove 3145 switch (break_type) 3146 { 3147 case '0': // remove software breakpoint 3148 case '1': // remove hardware breakpoint 3149 if (DNBBreakpointClear (pid, addr)) 3150 { 3151 return SendPacket ("OK"); 3152 } 3153 else 3154 { 3155 return SendPacket ("E08"); 3156 } 3157 break; 3158 3159 case '2': // remove write watchpoint 3160 case '3': // remove read watchpoint 3161 case '4': // remove access watchpoint 3162 if (DNBWatchpointClear (pid, addr)) 3163 { 3164 return SendPacket ("OK"); 3165 } 3166 else 3167 { 3168 return SendPacket ("E08"); 3169 } 3170 break; 3171 3172 default: 3173 break; 3174 } 3175 } 3176 return HandlePacket_UNIMPLEMENTED(p); 3177 } 3178 3179 // Extract the thread number from the thread suffix that might be appended to 3180 // thread specific packets. This will only be enabled if m_thread_suffix_supported 3181 // is true. 3182 nub_thread_t 3183 RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p) 3184 { 3185 if (m_thread_suffix_supported) 3186 { 3187 nub_thread_t tid = INVALID_NUB_THREAD; 3188 if (p) 3189 { 3190 const char *tid_cstr = strstr (p, "thread:"); 3191 if (tid_cstr) 3192 { 3193 tid_cstr += strlen ("thread:"); 3194 tid = strtoul(tid_cstr, NULL, 16); 3195 } 3196 } 3197 return tid; 3198 } 3199 return GetCurrentThread(); 3200 3201 } 3202 3203 /* 'p XX' 3204 print the contents of register X */ 3205 3206 rnb_err_t 3207 RNBRemote::HandlePacket_p (const char *p) 3208 { 3209 if (g_num_reg_entries == 0) 3210 InitializeRegisters (); 3211 3212 if (p == NULL || *p == '\0') 3213 { 3214 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3215 } 3216 if (!m_ctx.HasValidProcessID()) 3217 { 3218 return SendPacket ("E15"); 3219 } 3220 nub_process_t pid = m_ctx.ProcessID(); 3221 errno = 0; 3222 char *tid_cstr = NULL; 3223 uint32_t reg = strtoul (p + 1, &tid_cstr, 16); 3224 if (errno != 0 && reg == 0) 3225 { 3226 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet"); 3227 } 3228 3229 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr); 3230 if (tid == INVALID_NUB_THREAD) 3231 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3232 3233 const register_map_entry_t *reg_entry; 3234 3235 if (reg < g_num_reg_entries) 3236 reg_entry = &g_reg_entries[reg]; 3237 else 3238 reg_entry = NULL; 3239 3240 std::ostringstream ostrm; 3241 if (reg_entry == NULL) 3242 { 3243 DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg); 3244 ostrm << "00000000"; 3245 } 3246 else if (reg_entry->nub_info.reg == -1) 3247 { 3248 if (reg_entry->nub_info.size > 0) 3249 { 3250 std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0'); 3251 append_hex_value(ostrm, zeros.data(), zeros.size(), false); 3252 } 3253 } 3254 else 3255 { 3256 register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL); 3257 } 3258 return SendPacket (ostrm.str()); 3259 } 3260 3261 /* 'Pnn=rrrrr' 3262 Set register number n to value r. 3263 n and r are hex strings. */ 3264 3265 rnb_err_t 3266 RNBRemote::HandlePacket_P (const char *p) 3267 { 3268 if (g_num_reg_entries == 0) 3269 InitializeRegisters (); 3270 3271 if (p == NULL || *p == '\0') 3272 { 3273 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet"); 3274 } 3275 if (!m_ctx.HasValidProcessID()) 3276 { 3277 return SendPacket ("E28"); 3278 } 3279 3280 nub_process_t pid = m_ctx.ProcessID(); 3281 3282 StringExtractor packet (p); 3283 3284 const char cmd_char = packet.GetChar(); 3285 // Register ID is always in big endian 3286 const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX); 3287 const char equal_char = packet.GetChar(); 3288 3289 if (cmd_char != 'P') 3290 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet"); 3291 3292 if (reg == UINT32_MAX) 3293 return SendPacket ("E29"); 3294 3295 if (equal_char != '=') 3296 return SendPacket ("E30"); 3297 3298 const register_map_entry_t *reg_entry; 3299 3300 if (reg >= g_num_reg_entries) 3301 return SendPacket("E47"); 3302 3303 reg_entry = &g_reg_entries[reg]; 3304 3305 if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1) 3306 { 3307 DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg); 3308 return SendPacket("E48"); 3309 } 3310 3311 DNBRegisterValue reg_value; 3312 reg_value.info = reg_entry->nub_info; 3313 packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc); 3314 3315 nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p); 3316 if (tid == INVALID_NUB_THREAD) 3317 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet"); 3318 3319 if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, ®_value)) 3320 { 3321 return SendPacket ("E32"); 3322 } 3323 return SendPacket ("OK"); 3324 } 3325 3326 /* 'c [addr]' 3327 Continue, optionally from a specified address. */ 3328 3329 rnb_err_t 3330 RNBRemote::HandlePacket_c (const char *p) 3331 { 3332 const nub_process_t pid = m_ctx.ProcessID(); 3333 3334 if (pid == INVALID_NUB_PROCESS) 3335 return SendPacket ("E23"); 3336 3337 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 3338 3339 if (*(p + 1) != '\0') 3340 { 3341 action.tid = GetContinueThread(); 3342 errno = 0; 3343 action.addr = strtoull (p + 1, NULL, 16); 3344 if (errno != 0 && action.addr == 0) 3345 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet"); 3346 } 3347 3348 DNBThreadResumeActions thread_actions; 3349 thread_actions.Append(action); 3350 thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0); 3351 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3352 return SendPacket ("E25"); 3353 // Don't send an "OK" packet; response is the stopped/exited message. 3354 return rnb_success; 3355 } 3356 3357 rnb_err_t 3358 RNBRemote::HandlePacket_MemoryRegionInfo (const char *p) 3359 { 3360 /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code) 3361 for the memory region containing a given address and return that information. 3362 3363 Users of this packet must be prepared for three results: 3364 3365 Region information is returned 3366 Region information is unavailable for this address because the address is in unmapped memory 3367 Region lookup cannot be performed on this platform or process is not yet launched 3368 This packet isn't implemented 3369 3370 Examples of use: 3371 qMemoryRegionInfo:3a55140 3372 start:3a50000,size:100000,permissions:rwx 3373 3374 qMemoryRegionInfo:0 3375 error:address in unmapped region 3376 3377 qMemoryRegionInfo:3a551140 (on a different platform) 3378 error:region lookup cannot be performed 3379 3380 qMemoryRegionInfo 3381 OK // this packet is implemented by the remote nub 3382 */ 3383 3384 p += sizeof ("qMemoryRegionInfo") - 1; 3385 if (*p == '\0') 3386 return SendPacket ("OK"); 3387 if (*p++ != ':') 3388 return SendPacket ("E67"); 3389 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) 3390 p += 2; 3391 3392 errno = 0; 3393 uint64_t address = strtoul (p, NULL, 16); 3394 if (errno != 0 && address == 0) 3395 { 3396 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); 3397 } 3398 3399 DNBRegionInfo region_info = { 0, 0, 0 }; 3400 DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info); 3401 std::ostringstream ostrm; 3402 3403 // start:3a50000,size:100000,permissions:rwx 3404 ostrm << "start:" << std::hex << region_info.addr << ';'; 3405 3406 if (region_info.size > 0) 3407 ostrm << "size:" << std::hex << region_info.size << ';'; 3408 3409 if (region_info.permissions) 3410 { 3411 ostrm << "permissions:"; 3412 3413 if (region_info.permissions & eMemoryPermissionsReadable) 3414 ostrm << 'r'; 3415 if (region_info.permissions & eMemoryPermissionsWritable) 3416 ostrm << 'w'; 3417 if (region_info.permissions & eMemoryPermissionsExecutable) 3418 ostrm << 'x'; 3419 ostrm << ';'; 3420 } 3421 return SendPacket (ostrm.str()); 3422 } 3423 3424 // qGetProfileData;scan_type:0xYYYYYYY 3425 rnb_err_t 3426 RNBRemote::HandlePacket_GetProfileData (const char *p) 3427 { 3428 nub_process_t pid = m_ctx.ProcessID(); 3429 if (pid == INVALID_NUB_PROCESS) 3430 return SendPacket ("OK"); 3431 3432 StringExtractor packet(p += sizeof ("qGetProfileData")); 3433 DNBProfileDataScanType scan_type = eProfileAll; 3434 std::string name; 3435 std::string value; 3436 while (packet.GetNameColonValue(name, value)) 3437 { 3438 if (name.compare ("scan_type") == 0) 3439 { 3440 std::istringstream iss(value); 3441 uint32_t int_value = 0; 3442 if (iss >> std::hex >> int_value) 3443 { 3444 scan_type = (DNBProfileDataScanType)int_value; 3445 } 3446 } 3447 } 3448 3449 std::string data = DNBProcessGetProfileData(pid, scan_type); 3450 if (!data.empty()) 3451 { 3452 return SendPacket (data.c_str()); 3453 } 3454 else 3455 { 3456 return SendPacket ("OK"); 3457 } 3458 } 3459 3460 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY 3461 rnb_err_t 3462 RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p) 3463 { 3464 nub_process_t pid = m_ctx.ProcessID(); 3465 if (pid == INVALID_NUB_PROCESS) 3466 return SendPacket ("OK"); 3467 3468 StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling")); 3469 bool enable = false; 3470 uint64_t interval_usec = 0; 3471 DNBProfileDataScanType scan_type = eProfileAll; 3472 std::string name; 3473 std::string value; 3474 while (packet.GetNameColonValue(name, value)) 3475 { 3476 if (name.compare ("enable") == 0) 3477 { 3478 enable = strtoul(value.c_str(), NULL, 10) > 0; 3479 } 3480 else if (name.compare ("interval_usec") == 0) 3481 { 3482 interval_usec = strtoul(value.c_str(), NULL, 10); 3483 } 3484 else if (name.compare ("scan_type") == 0) 3485 { 3486 std::istringstream iss(value); 3487 uint32_t int_value = 0; 3488 if (iss >> std::hex >> int_value) 3489 { 3490 scan_type = (DNBProfileDataScanType)int_value; 3491 } 3492 } 3493 } 3494 3495 if (interval_usec == 0) 3496 { 3497 enable = 0; 3498 } 3499 3500 DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type); 3501 return SendPacket ("OK"); 3502 } 3503 3504 rnb_err_t 3505 RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p) 3506 { 3507 /* This packet simply returns the number of supported hardware watchpoints. 3508 3509 Examples of use: 3510 qWatchpointSupportInfo: 3511 num:4 3512 3513 qWatchpointSupportInfo 3514 OK // this packet is implemented by the remote nub 3515 */ 3516 3517 p += sizeof ("qWatchpointSupportInfo") - 1; 3518 if (*p == '\0') 3519 return SendPacket ("OK"); 3520 if (*p++ != ':') 3521 return SendPacket ("E67"); 3522 3523 errno = 0; 3524 uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID()); 3525 std::ostringstream ostrm; 3526 3527 // size:4 3528 ostrm << "num:" << std::dec << num << ';'; 3529 return SendPacket (ostrm.str()); 3530 } 3531 3532 /* 'C sig [;addr]' 3533 Resume with signal sig, optionally at address addr. */ 3534 3535 rnb_err_t 3536 RNBRemote::HandlePacket_C (const char *p) 3537 { 3538 const nub_process_t pid = m_ctx.ProcessID(); 3539 3540 if (pid == INVALID_NUB_PROCESS) 3541 return SendPacket ("E36"); 3542 3543 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS }; 3544 int process_signo = -1; 3545 if (*(p + 1) != '\0') 3546 { 3547 action.tid = GetContinueThread(); 3548 char *end = NULL; 3549 errno = 0; 3550 process_signo = strtoul (p + 1, &end, 16); 3551 if (errno != 0) 3552 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet"); 3553 else if (*end == ';') 3554 { 3555 errno = 0; 3556 action.addr = strtoull (end + 1, NULL, 16); 3557 if (errno != 0 && action.addr == 0) 3558 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet"); 3559 } 3560 } 3561 3562 DNBThreadResumeActions thread_actions; 3563 thread_actions.Append (action); 3564 thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal); 3565 if (!DNBProcessSignal(pid, process_signo)) 3566 return SendPacket ("E52"); 3567 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3568 return SendPacket ("E38"); 3569 /* Don't send an "OK" packet; response is the stopped/exited message. */ 3570 return rnb_success; 3571 } 3572 3573 //---------------------------------------------------------------------- 3574 // 'D' packet 3575 // Detach from gdb. 3576 //---------------------------------------------------------------------- 3577 rnb_err_t 3578 RNBRemote::HandlePacket_D (const char *p) 3579 { 3580 SendPacket ("OK"); 3581 if (m_ctx.HasValidProcessID()) 3582 DNBProcessDetach(m_ctx.ProcessID()); 3583 return rnb_success; 3584 } 3585 3586 /* 'k' 3587 Kill the inferior process. */ 3588 3589 rnb_err_t 3590 RNBRemote::HandlePacket_k (const char *p) 3591 { 3592 DNBLog ("Got a 'k' packet, killing the inferior process."); 3593 // No response to should be sent to the kill packet 3594 if (m_ctx.HasValidProcessID()) 3595 DNBProcessKill (m_ctx.ProcessID()); 3596 SendPacket ("W09"); 3597 return rnb_success; 3598 } 3599 3600 rnb_err_t 3601 RNBRemote::HandlePacket_stop_process (const char *p) 3602 { 3603 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt 3604 #if defined(TEST_EXIT_ON_INTERRUPT) 3605 rnb_err_t err = HandlePacket_k (p); 3606 m_comm.Disconnect(true); 3607 return err; 3608 #else 3609 DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP); 3610 //DNBProcessSignal (m_ctx.ProcessID(), SIGINT); 3611 // Do not send any response packet! Wait for the stop reply packet to naturally happen 3612 return rnb_success; 3613 #endif 3614 } 3615 3616 /* 's' 3617 Step the inferior process. */ 3618 3619 rnb_err_t 3620 RNBRemote::HandlePacket_s (const char *p) 3621 { 3622 const nub_process_t pid = m_ctx.ProcessID(); 3623 if (pid == INVALID_NUB_PROCESS) 3624 return SendPacket ("E32"); 3625 3626 // Hardware supported stepping not supported on arm 3627 nub_thread_t tid = GetContinueThread (); 3628 if (tid == 0 || tid == -1) 3629 tid = GetCurrentThread(); 3630 3631 if (tid == INVALID_NUB_THREAD) 3632 return SendPacket ("E33"); 3633 3634 DNBThreadResumeActions thread_actions; 3635 thread_actions.AppendAction(tid, eStateStepping); 3636 3637 // Make all other threads stop when we are stepping 3638 thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0); 3639 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3640 return SendPacket ("E49"); 3641 // Don't send an "OK" packet; response is the stopped/exited message. 3642 return rnb_success; 3643 } 3644 3645 /* 'S sig [;addr]' 3646 Step with signal sig, optionally at address addr. */ 3647 3648 rnb_err_t 3649 RNBRemote::HandlePacket_S (const char *p) 3650 { 3651 const nub_process_t pid = m_ctx.ProcessID(); 3652 if (pid == INVALID_NUB_PROCESS) 3653 return SendPacket ("E36"); 3654 3655 DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS }; 3656 3657 if (*(p + 1) != '\0') 3658 { 3659 char *end = NULL; 3660 errno = 0; 3661 action.signal = strtoul (p + 1, &end, 16); 3662 if (errno != 0) 3663 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet"); 3664 else if (*end == ';') 3665 { 3666 errno = 0; 3667 action.addr = strtoull (end + 1, NULL, 16); 3668 if (errno != 0 && action.addr == 0) 3669 { 3670 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet"); 3671 } 3672 } 3673 } 3674 3675 action.tid = GetContinueThread (); 3676 if (action.tid == 0 || action.tid == -1) 3677 return SendPacket ("E40"); 3678 3679 nub_state_t tstate = DNBThreadGetState (pid, action.tid); 3680 if (tstate == eStateInvalid || tstate == eStateExited) 3681 return SendPacket ("E37"); 3682 3683 3684 DNBThreadResumeActions thread_actions; 3685 thread_actions.Append (action); 3686 3687 // Make all other threads stop when we are stepping 3688 thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0); 3689 if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize())) 3690 return SendPacket ("E39"); 3691 3692 // Don't send an "OK" packet; response is the stopped/exited message. 3693 return rnb_success; 3694 } 3695 3696 rnb_err_t 3697 RNBRemote::HandlePacket_qHostInfo (const char *p) 3698 { 3699 std::ostringstream strm; 3700 3701 uint32_t cputype, is_64_bit_capable; 3702 size_t len = sizeof(cputype); 3703 bool promoted_to_64 = false; 3704 if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) 3705 { 3706 len = sizeof (is_64_bit_capable); 3707 if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) 3708 { 3709 if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0)) 3710 { 3711 promoted_to_64 = true; 3712 cputype |= CPU_ARCH_ABI64; 3713 } 3714 } 3715 3716 strm << "cputype:" << std::dec << cputype << ';'; 3717 } 3718 3719 uint32_t cpusubtype; 3720 len = sizeof(cpusubtype); 3721 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) 3722 { 3723 if (promoted_to_64 && 3724 cputype == CPU_TYPE_X86_64 && 3725 cpusubtype == CPU_SUBTYPE_486) 3726 cpusubtype = CPU_SUBTYPE_X86_64_ALL; 3727 3728 strm << "cpusubtype:" << std::dec << cpusubtype << ';'; 3729 } 3730 3731 // The OS in the triple should be "ios" or "macosx" which doesn't match our 3732 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 3733 // this for now. 3734 if (cputype == CPU_TYPE_ARM) 3735 { 3736 strm << "ostype:ios;"; 3737 // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 3738 strm << "watchpoint_exceptions_received:before;"; 3739 } 3740 else 3741 { 3742 strm << "ostype:macosx;"; 3743 strm << "watchpoint_exceptions_received:after;"; 3744 } 3745 // char ostype[64]; 3746 // len = sizeof(ostype); 3747 // if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0) 3748 // { 3749 // len = strlen(ostype); 3750 // std::transform (ostype, ostype + len, ostype, tolower); 3751 // strm << "ostype:" << std::dec << ostype << ';'; 3752 // } 3753 3754 strm << "vendor:apple;"; 3755 3756 #if defined (__LITTLE_ENDIAN__) 3757 strm << "endian:little;"; 3758 #elif defined (__BIG_ENDIAN__) 3759 strm << "endian:big;"; 3760 #elif defined (__PDP_ENDIAN__) 3761 strm << "endian:pdp;"; 3762 #endif 3763 3764 if (promoted_to_64) 3765 strm << "ptrsize:8;"; 3766 else 3767 strm << "ptrsize:" << std::dec << sizeof(void *) << ';'; 3768 return SendPacket (strm.str()); 3769 } 3770 3771 rnb_err_t 3772 RNBRemote::HandlePacket_qGDBServerVersion (const char *p) 3773 { 3774 std::ostringstream strm; 3775 3776 if (DEBUGSERVER_PROGRAM_NAME) 3777 strm << "name:" DEBUGSERVER_PROGRAM_NAME ";"; 3778 else 3779 strm << "name:debugserver;"; 3780 strm << "version:" << DEBUGSERVER_VERSION_NUM << ";"; 3781 3782 return SendPacket (strm.str()); 3783 } 3784 3785 // Note that all numeric values returned by qProcessInfo are hex encoded, 3786 // including the pid and the cpu type. 3787 3788 rnb_err_t 3789 RNBRemote::HandlePacket_qProcessInfo (const char *p) 3790 { 3791 nub_process_t pid; 3792 std::ostringstream rep; 3793 3794 // If we haven't run the process yet, return an error. 3795 if (!m_ctx.HasValidProcessID()) 3796 return SendPacket ("E68"); 3797 3798 pid = m_ctx.ProcessID(); 3799 3800 rep << "pid:" << std::hex << pid << ";"; 3801 3802 int procpid_mib[4]; 3803 procpid_mib[0] = CTL_KERN; 3804 procpid_mib[1] = KERN_PROC; 3805 procpid_mib[2] = KERN_PROC_PID; 3806 procpid_mib[3] = pid; 3807 struct kinfo_proc proc_kinfo; 3808 size_t proc_kinfo_size = sizeof(struct kinfo_proc); 3809 3810 if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) 3811 { 3812 if (proc_kinfo_size > 0) 3813 { 3814 rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";"; 3815 rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";"; 3816 rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";"; 3817 rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";"; 3818 if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) 3819 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";"; 3820 } 3821 } 3822 3823 cpu_type_t cputype = DNBProcessGetCPUType (pid); 3824 if (cputype == 0) 3825 { 3826 DNBLog ("Unable to get the process cpu_type, making a best guess."); 3827 cputype = best_guess_cpu_type(); 3828 } 3829 3830 if (cputype != 0) 3831 { 3832 rep << "cputype:" << std::hex << cputype << ";"; 3833 } 3834 3835 uint32_t cpusubtype; 3836 size_t cpusubtype_len = sizeof(cpusubtype); 3837 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0) 3838 { 3839 if (cputype == CPU_TYPE_X86_64 && cpusubtype == CPU_SUBTYPE_486) 3840 { 3841 cpusubtype = CPU_SUBTYPE_X86_64_ALL; 3842 } 3843 3844 rep << "cpusubtype:" << std::hex << cpusubtype << ';'; 3845 } 3846 3847 // The OS in the triple should be "ios" or "macosx" which doesn't match our 3848 // "Darwin" which gets returned from "kern.ostype", so we need to hardcode 3849 // this for now. 3850 if (cputype == CPU_TYPE_ARM) 3851 rep << "ostype:ios;"; 3852 else 3853 rep << "ostype:macosx;"; 3854 3855 rep << "vendor:apple;"; 3856 3857 #if defined (__LITTLE_ENDIAN__) 3858 rep << "endian:little;"; 3859 #elif defined (__BIG_ENDIAN__) 3860 rep << "endian:big;"; 3861 #elif defined (__PDP_ENDIAN__) 3862 rep << "endian:pdp;"; 3863 #endif 3864 3865 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE) 3866 nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid); 3867 kern_return_t kr; 3868 x86_thread_state_t gp_regs; 3869 mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT; 3870 kr = thread_get_state (thread, x86_THREAD_STATE, 3871 (thread_state_t) &gp_regs, &gp_count); 3872 if (kr == KERN_SUCCESS) 3873 { 3874 if (gp_regs.tsh.flavor == x86_THREAD_STATE64) 3875 rep << "ptrsize:8;"; 3876 else 3877 rep << "ptrsize:4;"; 3878 } 3879 #elif defined (__arm__) 3880 rep << "ptrsize:4;"; 3881 #endif 3882 3883 return SendPacket (rep.str()); 3884 } 3885 3886