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