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