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