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