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